Selecting nested iframe with selenium webdriver Chrome and C# - selenium-webdriver

I have a frame and inside that clicking a button opens an iFrame. my frame selection seems to work and i know my XPath is good (because it works in chrome) but my test always fails with
OpenQA.Selenium.WebDriverTimeoutException: Timed out after 5 seconds ---> OpenQA.Selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"xpath","selector":"//em[.='Job Selector']"}
attached are some images that show HTML and sources.
in my code I'm using:
// wait for menu frame to appear
wait.Until(ExpectedConditions.FrameToBeAvailableAndSwitchToIt(By.XPath("//frame[#id='menu']")));
// do a bunch of stuff
driver.SwitchTo().DefaultContent();
wait.Until(ExpectedConditions.FrameToBeAvailableAndSwitchToIt(By.XPath("//frame[#id='master']")));
// Add to running jobs: open iFrame
driver.FindElement(By.Id("ctl00_cphMain_cmdAdd")).Click();
//driver.SwitchTo().DefaultContent(); tried with and without this
wait.Until(ExpectedConditions.FrameToBeAvailableAndSwitchToIt(By.XPath("//iframe[#name='JobWindow']")));
// wait for SelectJob Window to appear tried several elements
//wait.Until(ExpectedConditions.ElementIsVisible(By.Id("RadWindowWrapper_ctl00_cphMain_JobWindow")));
wait.Until(ExpectedConditions.ElementIsVisible(By.XPath("//em[.='Job Selector']")));
Any suggestions on what I'm doing wrong

Finally got this to work:
wait.Until(ExpectedConditions.FrameToBeAvailableAndSwitchToIt(By.XPath("//iframe[#name='JobWindow']")));
IWebElement body = driver.FindElement(By.TagName("body"));
body.Click();
// wait for SelectJob Window to appear
IWebElement SaveButton = wait.Until(ExpectedConditions.ElementToBeClickable(By.Id("cmdSave")));
SaveButton.Click();
Without the body.click, no luck
Props to Jainish: https://stackoverflow.com/a/41500131/1667188

Related

File upload functionality of Selenium web driver for non-input button without AutoIt or Skuliii

I need to upload a document via Selenium WebDriver using Chromedriver. I have tried all the Action class and JavaScript stuff, but those do not work. I am assuming they do not work because those are relying on the button to be an input field, however, the upload button I'm dealing with is not. It's HTML looks like this:
Steps to reproduce:
Go to: https://www.fedex.com/apps/printonline/#!
Click on View Products under Marketing Material
Click on Get Started under Brochure
Click on Use your File to upload the file
Use Your File
I am able to click the use your file button, but I am not sure how I can upload the file.
driver.get("https://www.fedex.com/apps/printonline/#!");
driver.manage().window().maximize();
driver.manage().deleteAllCookies();
driver.manage().timeouts().pageLoadTimeout(40, TimeUnit.SECONDS);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
//Thread.sleep(6000);
if (driver.findElement(By.xpath("//area[#alt='close']")) != null) {
driver.findElement(By.xpath("//area[#alt='close']")).click();
}
driver.findElement(By.xpath("//a[#title='Marketing Materials']/child::button")).click();
Thread.sleep(1000);
driver.findElement(By.xpath("//a[#title='Get Started - Brochures']")).click();
Thread.sleep(1000);
WebElement element = driver.findElement(By.xpath("//*[#class='btn fxg-btn-orange mycomputer-upload-link']"));
((JavascriptExecutor)driver).executeScript("arguments[0].click()", element);
Ok so first of all get rid of those Thread.sleep(), use fluent wait with polling time, preferably as a function to locate the elements:
private WebElement waitFor(By locator) {
int timeout = 10;
FluentWait<WebDriver> wait = new FluentWait<>(driver)
.pollingEvery(Duration.ofMillis(200))
.withTimeout(Duration.ofSeconds(timeout))
.ignoring(NoSuchElementException.class);
return wait.until((driver) -> driver.findElement(locator));
}
Then you can click the buttons and upload the file like this:
waitFor(By.cssSelector("button.view-products")).click();
waitFor(By.cssSelector("a.get-started")).click();
waitFor(By.cssSelector("a.get-started")).click();
waitFor(By.cssSelector("input.file-upload")).sendKeys("path_to_my_file");
Notice I am using the input element to upload the file - I am not clicking the a link, as you do not need to do that. Just send the path directly to the input element.

Handling print window in selenium webdriver

There is a print button in my application. When I click on the button print windows open with cancel and print button.
I want to click on cancel button in the print window.
I know handling print window is not possible using selenium webdriver alone. I tried using Robot class. But it is not working.
WebDriver driver = (WebDriver) new ChromeDriver();
driver.get("https://www.joecolantonio.com/SeleniumTestPage.html");
driver.manage().window().maximize();
Thread.sleep(2000);
//clicking on the print button
driver.findElement(By.id("printButton")).click();
//print window opens
//creating robot class object
Robot r = new Robot();
r.delay(1000);
r.keyPress(KeyEvent.VK_ESCAPE);
r.keyRelease(KeyEvent.VK_ESCAPE);
The print window opens but nothing happens after that. I was expecting escape button will make the window exit but its does not happens. But manually when I press escape button print window disappears.
Actually you can handle print page window using javascript executor in selenium.
following codes are c#.
If your program is stuck after opening window.print(); which in my case it was happening, try to use the following javascript code instead:
setTimeout(function() { window.print(); }, 0);
this will release your application and you can work with the print page.
then you can switch to the print page simply by the following line:
driver.SwitchTo().Window(driver.WindowHandles.Last());
then you can get the JSPath of any element in print window and interact with it
(IWebElement)js.ExecuteScript($"return {JSPath}").Click();
A complete example of this, is as follows where print window will be opened then the cancel button will be clicked after 2 seconds.
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
js.ExecuteScript("setTimeout(function() { window.print(); }, 0);");
driver.SwitchTo().Window(driver.WindowHandles.Last());
Thread.Sleep(2000);
string JSPath = "document.querySelector('body>print-preview-app').shadowRoot.querySelector('#sidebar').shadowRoot.querySelector('print-preview-button-strip').shadowRoot.querySelector('cr-button.cancel-button')";
IWebElement cancelBtn = (IWebElement)js.ExecuteScript($"return {JSPath}");
cancelBtn.Click();
Since the elements in print window exist in the shadow root you cannot select them by selenium web driver that's why I used Javascript Executor to get the cancel button.
Use tab and then click escape.I think it works.
Using Robot is not something I would recommend to handling the print preview page as it will bite you back when you will be running your tests in Parallel mode.
You could click "Cancel" button as follows:
Switch to the Print Preview window using driver.switchTo() function:
driver.switchTo().window(driver.getWindowHandles().stream().filter(handle -> !handle.equals(driver.getWindowHandle())).findAny().get());
Find preview-app Shadow DOM element using i.e. XPath and convert it into a WebElement
WebElement printPreviewApp = driver.findElement(By.xpath("//print-preview-app"));
WebElement printPreviewAppContent = (WebElement) driver.executeScript("return arguments[0].shadowRoot", printPreviewApp);
Find preview-header Shadow DOM element using i.e. CSS and convert into a Selenium's Web Element
WebElement printPreviewHeader = printPreviewAppContent.findElement(By.cssSelector("print-preview-header"));
WebElement printPreviewHeaderContent = (WebElement) driver.executeScript("return arguments[0].shadowRoot", printPreviewHeader);
Locate Cancel button and click it
printPreviewHeaderContent.findElement(By.cssSelector("paper-button[class*=cancel]")).click();
Answer for someone else who still looking solution
To download save as a pdf from the print pop-up window from any web
Add argument
options.addArguments("kiosk-printing");
This will prevent to open any popups from clicking on any print button.But a window dialog folder will open to download the file as a pdf.
Now you need to input the file name and press enter button. For this, we will use the robot class
StringSelection s=new StringSelection("remotePetrol_report.pdf"); // Set the File Name
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(s,null);
//native keystrokes for CTRL, V, and ENTER keys
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);

How to make selenium 3.4.0 wait for page load?

I am using selenium web driver 3.4.0 to find the response time of a website..In earlier version , I have used
WebDriver wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("myId"))); to find the page loaded.
But these two lines of code not working for version 3.4.0. is there any other way to calculate the load time of a page? Or wait until the page gets loaded? Also I need to detect the modal dialog which will be loaded on button click.
I am implementing using dynamic web project in eclipse IDE.
I also need to wait for some moment until some click event finished loading Dom element. Wait.until() is not working for selenium 3.4.0. how to make selenium wait until some element is visible ?
You can use JavascriptExecutor to get the ready state of the page, and pass it as an expected condition to your wait.until()
Here is the reference code for this,
ExpectedCondition<Boolean> expectation = new
ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor) driver).executeScript("return document.readyState").toString().equals("complete");
}
};
try {
Thread.sleep(1000);
WebDriverWait wait = new WebDriverWait(LocalDriverManager.getDriver(), 30);
wait.until(expectation);
} catch (Throwable error) {
Assert.fail("Timeout waiting for Page Load Request to complete.");
}

Selenium webdriver: Unable to send keys In a new popup window

Using selenium web-driver I am trying to put region name In the text box In new popup screen and click on save button. I using the below script for that
String mainWindowHandle1=driver.getWindowHandle();
driver.switchTo().window(mainWindowHandle1 );
driver.findElement(By.id("MainContent_imgAddRegion")).click();
Thread.sleep(5000);
java.util.Set<String> s1 = driver.getWindowHandles();
Iterator<String> ite1 = s1.iterator();
while(ite1.hasNext())
{
String popupHandle=ite1.next().toString();
if(!popupHandle.contains(mainWindowHandle1))
{
driver.switchTo().window(popupHandle).findElement(By.id("txtRegionName")).sendKeys("South Region");
Thread.sleep(3000);
driver.findElement(By.id("txtRegionName")).sendKeys("South Region");
Thread.sleep(1000);
driver.findElement(By.id("btnSave")).click();
By doing this I am able to open the new popup screen to enter the region but, I am unable to send keys [region name] and save the text.Even I am not getting any failed report when I run the test.
This may be due to iFrames presence.
Look in the HTML code and check if the text field that you are trying to send keys to and the save button are included in some sort of iFrame.
If so, you will need to do something like:
driver.switchTo().defaultContent();
driver.switchTo().frame("framename");
driver.findElement(By.id("txtRegionName")).sendKeys("South Region");
driver.findElement(By.id("btnSave")).click();
Hope it helps!

Could not switch between browsers in selenium webdriver

Iam trying to switch between browser ie on click of a button it launches a new browser it
is finding the handle ..the problem is it is not able to find the object inside the new browser searched with id,xpath,name etc can some one give me any suggestion on the same.
also it is able to match the url as well.
please provide me the solution on the same.
below is the code.
//Previous screen
Set windows = driver1.getWindowHandles();
driver1.findElement(By.id("findButton")).click();
//switching handle for the new screen
driver1.switchTo().window("Customer Search");
driver1.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
int i = 1;
while(i<= 10){
for (String handle : driver1.getWindowHandles()) {
String myTitle = driver1.switchTo().window(handle).getTitle();
System.out.println("myTitle value : " +myTitle);
//customer search is the new window title
if(myTitle.equalsIgnoreCase("Customer Search")){
driver1.manage().window().maximize();
//if i pass the right url of the screen that is also matching here i have given dummy("sshsj")
if(driver1.getCurrentUrl().equalsIgnoreCase("sshsj"));
{
System.out.println("Url is matching");
//But not able the recognise the object on the new window.
driver1.findElement(By.xpath("html/body/left/form/table/tbody/tr[2]/td[1]/input")).sendKeys("kamal");
}
You can use JS to open a new window, it's faster.
IJavaScriptExecutor jscript = driver as IJavaScriptExecutor;
jscript.ExecuteScript("window.open()");
Then to switch windows, use the window handles:
List<string> handles = driver.WindowHandles.ToList<string>();
driver.SwitchTo().Window(handles.Last());
driver.get(url);
driver.findElement(By.xpath("html/body/left/form/table/tbody/tr[2]/td[1]/input")).sendKeys("kamal");
It is possible that the element may be present inside an iframe. In that case, you need to switch to that iframe before you can access any element inside the iframe.

Resources