NoSuchElementException after switching frames - java

UPDATE:
I think I saw the error, I configure again my Selenium IDE and recreate the test, and when i open in Eclipse i see this comments in code:
public void testEcsf3() throws Exception {
driver.get(baseUrl + "/something.com");
WebElement frame = driver.findElement(By.name("body"));
driver.switchTo().frame(frame);
//...
//code for navigate to the target page
//...
// ERROR: Caught exception [ERROR: Unsupported command [selectWindow | name=body | ]]
//Target page - another frame with name 'body'
driver.findElement(By.xpath("//tr[28]/td[2]/a/font")).click();// <-- target element in target page
//...
//code for navigate to the target page
//...
}
The problem is that the flow between pages have more of one frame with name 'body'(i can't change that), how i can make this work?
Thanks.
--
I'm trying to use a Selenium testcase(Ok in browser) using JUnit in Eclipse.
When I try to run the testcase I receive this error:
org.openqa.selenium.NoSuchElementException: Unable to locate element: {"method":"name","selector":"user"}
For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html
Driver info: org.openqa.selenium.firefox.FirefoxDriver
Note: the link mentioned in the error has no content!
This is the point of error:
driver.get(baseUrl + "/something.com");
driver.findElement(By.name("user")).sendKeys("aaa"); //<--
driver.findElement(By.name("password")).sendKeys("xxx");
driver.findElement(By.name("button0")).click();

I think your problem is the following:
This line: driver.get(baseUrl + "/something.com"); says him to go to this page, and the second line says him to search for the element immediately (so the browser dont have time at all to load the page)
So try this:
WebDriverWait wait;
wait = new WebDriverWait(webdriver, 10);
try{
wait.until(ExpectedConditions.visibilityOfElementLocated(By.name("user")));
}catch(TimeoutException e){
verifyElementPresent(locator);
}
or:
for (int second = 0;; second++) {
if (second >= 60)
fail("timeout");
try {
if (isElementPresent(By.name("user"))) {
break;
}
} catch (Exception e) {
}
Thread.sleep(1000);
}

Are you bound to the Driver? you could try this:
Selenium selenium = new WebDriverBackedSelenium(driver,"http://example.com");
selenium.open("http://something.com");
and optionally a
selenium.waitForPageToLoad();
The other things you tried to do are also simpler with the WebDriverBackedSelenium like
selenium.type(String field,String text);
you can look at that for the javadoc and deeper explanation

I stop for some days this project, and today i resolve the trouble.
This is the code:
for (String handle : driver.getWindowHandles()) {
driver.switchTo().window(handle);
}
WebElement body = driver.findElement(By.name("body"));
driver.switchTo().frame(body);
I hope this help someone.
Thanks.

Related

Check loading time in WebDriver test during execution

I use Selenium WebDriver 3.14 and test is executed in Chrome browser. I need to measure response time of a page in execution time to check it is under a predefined value. If it is greater than this value some additional actions should be done. So I need different solution than System.currentTimeMillis(), because check of this value should be done automatically in background. It is an AJAX like window, so when loading takes too long time, it should be closed by script. Window example:
The typical solution to this is a try/catch against a wait. E.g. if the next step is to click a button that shows once loading completes:
WebDriverWait wait = new WebDriverWait(driver, LOADING_TIMEOUT);
WebElement webElement;
try {
webElement = wait.until(elementToBeClickable(By.id(id)));
} catch (TimeoutException ex) {
// Close loading window
return;
}
webElement.click();
However, there is a common problem if you are using implicit timeouts in Selenium. This doesn't work too well, particularly if the implicit timeout is longer than the LOADING_TIMEOUT, as this slows down the polling cycle in the wait.until().
In this case, the simplest solution is to temporarily reduce the implicit timeout:
WebDriverWait wait = new WebDriverWait(driver, LOADING_TIMEOUT);
WebElement webElement;
try {
driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
webElement = wait.until(elementToBeClickable(By.id(id)));
} catch (TimeoutException ex) {
// Delay any further interaction until the timeout has been restored
webElement = null;
} finally {
driver.manage().timeouts().implicitlyWait(DEFAULT_TIMEOUT,
TimeUnit.SECONDS);
}
if (webElement != null)
webElement.click();
else
// Close loading window
If I understand correctly, you could decrease time in selenium.waitForPageToLoad("100000"); to a wanted predefined value, let us say 20 seconds. So if you want the page loading to stop if it is not loaded in 20 seconds, try something like this:
long start = System.currentTimeMillis();
try {
selenium.waitForPageToLoad("20000");
System.out.println("The page load is too long!");
} catch {
long timeToLoad= (System.currentTimeMillis()-start);
System.out.println("The page loaded in " +timeToLoad+ " seconds.");
}
You should try setting Logging Preferences through capability CapabilityType.LOGGING_PREFS for performance-log.
For example:
LoggingPreferences logs = new LoggingPreferences();
logs .enable(LogType.PERFORMANCE, Level.ALL);
caps.setCapability(CapabilityType.LOGGING_PREFS, logs);
you can get performance log entries as below.
for (LogEntry entry : driver.manage().logs().get(LogType.PERFORMANCE)) {
System.out.println(entry.toString());
//do the needful
}
I think you're looking for API testing not Automation Testing.
Postman API Testing Setup and Usage Tutorial
Hopefully this will help
edit:
Alternatively, a more lightweight solution for API testing:
Online API tester

Unable to handle alert using phantomJS in Java

I have a Java code as below and when I am running through PhantomJs getting "Unsupported Command Exception" but it is working fine if I run through firefox and chrome:-
Note: With phantomJs we could able to execute till 3rd step in below code.I searched in many blogs but those answers didn't solve my problem.
1. cvvField.sendKeys(cvcData);
2. proceedToPayBtn.click();
3. Reporter.log("Card details are submitted from payment UI page");
4. Alert a1=driver.switchTo().alert();
5. Reporter.log("Alert with text:"+a1.getText());
6. a1.accept();
Here cvvField and proceedToPayBtn are WebElements and cvcData have value as "111".
Error log:-
org.openqa.selenium.UnsupportedCommandException: Invalid Command Method -
{"headers":{"Accept-Encoding":"gzip,deflate","Cache-Control":"no-cache","Connection":"Keep-Alive","Host":"localhost:30462","User-Agent":"Apache-HttpClient/4.5.1 (Java/1.8.0_101)"},"httpVersion":"1.1","method":"GET","url":"/alert_text","urlParsed":{"anchor":"","query":"","file":"alert_text","directory":"/","path":"/alert_text","relative":"
/alert_text","port":"","host":"","password":"","user":"","userInfo":"","authority":"","protocol":"","source":"/alert_text","queryKey":{},"chunks":["alert_text"]},"urlOriginal":"/session/9e392a50-ce79-11e6-b24a-2b12cf1ec4d6/alert_text"}
Command duration or timeout: 31 milliseconds
I have edited above code as below but same error is coming.Please suggest
if (driver instanceof PhantomJSDriver)
{
JavascriptExecutor je = (JavascriptExecutor) driver;
je.executeScript("window.alert = function(){};");
je.executeScript("window.confirm = function(){return true;};");
System.out.println("Alert has been handled");
} else {
Alert a1 = driver.switchTo().alert();
a1.accept();
}
I am getting "Alert has been handled" in output console but alert is not handled.
Some issue due to wait time can be the source of your problem
The code above can help to wait until element is visible (since the wait of ngWebDriver or Selenium Webdriver are not compatible with PhantomJS)
public static String waitJSResponse(PhantomJSDriver driver, String script) {
String ReturnedValue = null;
int sleeper = 10;
Boolean flag = false;
int timeOut = 30000;
int i = 0;
while ((!flag) & ((i*sleeper)<timeOut)) {
try {
Thread.sleep(sleeper);
ReturnedValue = (String) driver.executeScript(script);
} catch (Exception e) {
flag = false;
i++;
}
if (ReturnedValue != null) {
flag = true;
System.out.println("Overall wait time is : "+(i * sleeper)+" ms \n\r");
break;
}
}
return ReturnedValue;
}
This code will wait 10ms then verify that the element is visble, if there is an exception, it will loop again.
The returned value must be a text, an object or anything that is not null.
the script value must be your JS script to get the correct element.
Hope it work.
I tried the above code by:-
1.Creating a class "Test" and writing above method in it.
2.Above method is called by creating an object(TestObject) as
TestObject.waitJSResponse((PhantomJSDriver) driver, "window.confirm = function(){return true;};");
But ReturnedValue in
try
{
Thread.sleep(sleeper);
ReturnedValue = (String) driver.executeScript(script);
System.out.println(ReturnedValue);
}
returns null.So Can u please help with this?

assertEquals works in selenium but not in JAVA

I made a testcase in selenium which repeats perfectly and then exported it to JAVA /JUnit4 / Webdriver :
public void emailInvalid() throws Exception {
driver.get(baseUrl + "/test/contacts.html");
driver.findElement(By.name("companyName")).clear();
driver.findElement(By.name("companyName")).sendKeys("testcomp");
driver.findElement(By.name("phone")).clear();
driver.findElement(By.name("phone")).sendKeys("45454545");
driver.findElement(By.name("email")).clear();
driver.findElement(By.name("email")).sendKeys("test.ee");
driver.findElement(By.name("message")).clear();
driver.findElement(By.name("message")).sendKeys("qwerty");
driver.findElement(By.cssSelector("button.submit")).click();
assertEquals("Not valid email.", driver.findElement(By.cssSelector("span.error.notValidEmail")).getText());
}
The test fails in Java because assertEquals can't get the text its looking for. The error message is
org.junit.ComparisonFailure: expected:<[Not valid email]> but was:<[]>
In most cases your problem would be bad synchronization.
Your element is found but its text is empty.
You can try touse webDriverWait with expecting the stalenessOf, you can change the way an element is located by using its expected text in the locator or you can add very short sleep
Apparently the element cannot be found by the css selector and thereby the assertion fails.
Maybe the element is loaded after the assertion is executed or the element is not loaded at all.
Try to wait for the element to be loaded before the assertion using the following code:
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("span.error.notValidEmail")));
assertEquals("Not valid email.", driver.findElement(By.cssSelector("span.error.notValidEmail")).getText());
If this is not the case then check again if the selector is correct.
Also check what getText() returns by printing the actual string.
Try waiting for the text present and use an assert if the text is located within the specified time interval.
Also be sure to check the uniqueness of the element using your css locator.
public void emailInvalid() throws Exception {
driver.get(baseUrl + "/test/contacts.html");
driver.findElement(By.name("companyName")).clear();
driver.findElement(By.name("companyName")).sendKeys("testcomp");
driver.findElement(By.name("phone")).clear();
driver.findElement(By.name("phone")).sendKeys("45454545");
driver.findElement(By.name("email")).clear();
driver.findElement(By.name("email")).sendKeys("test.ee");
driver.findElement(By.name("message")).clear();
driver.findElement(By.name("message")).sendKeys("qwerty");
driver.findElement(By.cssSelector("button.submit")).click();
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("span.error.notValidEmail")));
assertTrue(waitForTextPresent(driver, By.cssSelector("span.error.notValidEmail"), "Not valid email.", 20));
}
public static boolean waitForTextPresent(WebDriver driver, By locator, String text, int timeOut) {
int i = 0;
int WAIT_SLEEP_INTERVAL = 500;
boolean isTextPresent = false;
while (!isTextPresent) {
i = i + 1;
try{
Thread.sleep(WAIT_SLEEP_INTERVAL);
} catch(Exception e) {
//do nothing
}
isTextPresent = driver.findElement(locator).getText().contains(text);
if (i * WAIT_SLEEP_INTERVAL >= timeOut) {
return false;
}
}
return true;
}
Actually you can also do a get text after the line:
wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("span.error.notValidEmail")));
System.out.println(driver.findElement(By.cssSelector("span.error.notValidEmail")).getText());
And see if you are getting the text that you are looking for. You may not need to use the method waitForTextPresent in that case.
Try to check what value of baseUrl. Is it equals "http://yousite" or just ".." or so on? Try to debug this method may be Java didn't found correct url. Or use logging and logging baseUrl + "/test/contacts.html". It look like problem with baseUrl.

StateElementReferenceException in Selenium

I am getting a StateElementReferenceException when I try to perform a drag-and-drop action, see the code snippets below. Can anyone please help to solve this with appropriate suggestions and explanations?
#Test(priority=4)
public void addUserBySearch() {
driver.findElement(By.xpath(OR.getProperty("btnUserGroup"))).click();
driver.findElement(By.xpath(OR.getProperty("btnCreateUG"))).click();
driver.findElement(By.xpath(OR.getProperty("textUGName"))).sendKeys("UserGroup:" + Utils.randGen());
driver.findElement(By.xpath(OR.getProperty("userSearchField"))).sendKeys("testuser2", Keys.ENTER);
source = driver.findElement(By.xpath(OR.getProperty("searchedUserSource")));
destination = driver.findElement(By.xpath(OR.getProperty("userDestination")));
waitUntilElementVisible(30, source);
dragAndDrop(source, destination);
driver.findElement(By.xpath(OR.getProperty("btnScheduleNow"))).click();
}
public void waitUntilElementVisible(int seconds, WebElement element) {
WebDriverWait explicitWait = new WebDriverWait(driver, seconds);
explicitWait.until(ExpectedConditions.visibilityOf(element));
}
public void dragAndDrop(WebElement sourceElement, WebElement destinationElement){
try {
if (sourceElement.isDisplayed() && destinationElement.isDisplayed()) {
Actions action = new Actions(driver);
action.dragAndDrop(sourceElement, destinationElement).build().perform();
}
else {
System.out.println("Element not found to drag and drop");
}
}
catch (StaleElementReferenceException exc) {
exc.printStackTrace();
}
catch (NoSuchElementException exc) {
exc.printStackTrace();
}
}
btnUserGroup = //*[text()='User Groups']
btnCreateUG = //*[#id='stage']/div/div[2]/div/div/div[2]/div[3]/a
textUGName = //input[#id='user_group_name']
btnScheduleNow = //*[text()='Schedule Now']
userDestination = //*[#class='ConnectedList ConnectedListAdded']/div[2]/ul
userSearchField = //div[#class='ConnectedListConnectedListSelect']/div[2]/div[1]/ul/li[1]/input
searchedUserSource = //div[#class='ConnectedList ConnectedListSelect']/div[2]/ul/li/span[5]
Exception:
org.openqa.selenium.StaleElementReferenceException: Element not found in the cache - perhaps the page has changed since it was looked up
Command duration or timeout: 10.28 seconds
A StaleReferenceException occurs for mainly one of two reasons:
The element has been deleted entirely.
The element is no longer attached to the DOM.
One possible solution to your problem is to surround dragAndDrop() in a while loop, and continually try and dragAndDrop() until you succeed. So something like the following:
boolean draggedAndDropped = false;
while(!draggedAndDropped ) {
try{
source = driver.findElement(By.xpath(OR.getProperty("searchedUserSource")));
destination = driver.findElement(By.xpath(OR.getProperty("userDestination")));
dragAndDrop(source, destination);
draggedAndDropped = true;
} catch(StaleElementReferenceException e) {
System.out.println("StaleElementReferenceException caught, trying again");
}
}
Of course its never a good idea idea to give allow a loop to loop infinitely, so you will want to incorporate a max attempts into the while loop.
As stated by the Selenium project's documentation, a StaleElementReferenceException can be thrown for two reasons:
The element has been deleted entirely.
The element is no longer attached to the DOM.
As such, I suspect that a race condition is occurring at this point:
driver.findElement(By.xpath(OR.getProperty("userSearchField"))).sendKeys("testuser2", Keys.ENTER);
source = driver.findElement(By.xpath(OR.getProperty("searchedUserSource")));
After you've entered "testuser2" in the "userSearchField" WebElement you've used Keys.ENTER to presumably submit the search query - the problem may be occurring because WebDriver is retrieving a reference to the "searchedUserSource" WebElement before the page has fully refreshed.
To get around this, you could try using the WebElement.submit() method to submit the search as it blocks the WebDriver's execution until the page has finished changing (i.e. finished displaying the search result).
Below is an example of how you could implement this:
driver.findElement(By.xpath(OR.getProperty("userSearchField"))).sendKeys("testuser2").submit();
source = driver.findElement(By.xpath(OR.getProperty("searchedUserSource")));

Selenium if sentence and the click else find some other and click

I have a problem with Selenium Webdriver. Following code is where my headache is at:
boolean FindPrimary=driver.findElement(By.xpath("//*[#id='started_in_business_view']/p")) != null;
if(FindPrimary){
driver.findElement(By.xpath("//*[#id='started_in_business_view']/p")).click();
}
else
driver.findElement(By.xpath("//*[#id='started_in_business_view']/div")).click();
The excepted result that I want to achieve is that the driver searches for the element and clicks it. And if it doesn´t find it ,the driver clicks the optional element.
I assume you received a NoSuchElement in the first line.
boolean findPrimary=driver.findElements(By.xpath("//*[#id='started_in_business_view']/p")).size() > 0;
if(findPrimary){
driver.findElement(By.xpath("//*[#id='started_in_business_view']/p")).click();
}
else
driver.findElement(By.xpath("//*[#id='started_in_business_view']/div")).click();
I would do it with
try{
driver.findElement(By.xpath("//*[#id='started_in_business_view']/p")).click();
} catch (Exception exc) {
driver.findElement(By.xpath("//*[#id='started_in_business_view']/div")).click();
}
if you're xpaths are correct, should work...

Categories