I am pretty new to all the Automated Testing thing and recently I have been having trouble with selenium because sometimes fails finding certain input fields / buttons.
I added explicit waits for every element in the page, so the test is supposed to wait for that element to appear on screen, but sometimes randomly fails to do so. I will attach the latest error thrown by selenium in a simple test.
This is one of the tests that I am trying to run and randomly fails:
#Test
public void createTaskTest(){
generateTestEnvironmentSalesForceHomePage();
this.home.clickTasksTab();
generateTestEnvironmentTaskPage();
this.taskspage.clickNewTask();
generateTestEnvironmentNewTask();
this.newtask.setDateField("12/30/2016");
this.newtask.setCostField("1500");
this.newtask.setType("Personal Appointment");
this.newtask.setPaymentType("End of the day");
this.newtask.setDoctor("House");
this.newtask.submitTask();
Assert.assertTrue(this.newtask.checkDetailsPage());
}
Error thrown by selenium:
org.openqa.selenium.TimeoutException: Expected condition failed: waiting for visibility of element located by By.cssSelector: span.dateOnlyInput>input (tried for 130 second(s) with 500 MILLISECONDS interval)
Here is the method to find the 'missing' date input:
public void setDateField(String date){
WebDriverWait wait = new WebDriverWait(this.driver,130);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("span.dateOnlyInput>input")));
this.driver.findElement(By.cssSelector("span.dateOnlyInput>input")).sendKeys(date);
}
Related
Is it not possible to have both SUCCCESS and FAILURE Outcome in the story?
Lifecycle:
After:
Outcome: FAILURE
Given I capture page screenshot
Given I close browser
Outcome: SUCCESS
Given I close browser
Scenario: Sample one
Given I open browser
When I do something
Scenario: Sample two
Given I open browser
When I do another thing
For example, for failures I want to take a screenshot before closing the browser. If successful I just want to close the browser.
I know I can just close the browser at the end of all my scenarios and only have the failure outcome remain. I would like to know if there is a way to do this in the Lifecycle After.
Thanks.
Quoting OP:
For example, for failures I want to take a screenshot before closing the browser. If successful I just want to close the browser.
Now, the interesting question will be which framework are you using for your assertions?
I'll assume you use Junit which comes bundled with JBehave as JBehave relies on knowing there is an error by JUnit's thrown exception.
The idea is to:
a) throw an exception when an error occurs (so need to check on every step)
b) take a screenshot
c) continue with testing (i.e. closing the browser)
So in order to throw an exception, you really do no need to do much as this is done automatically when using JUnit's Assert statement.
so for example
Assert(username.equals("expected_user").isTrue();
If the above fails an exception will be thrown.
You can capture it as such:
public class RunnerExtension implements AfterTestExecutionCallback {
#Override
public void afterTestExecution(ExtensionContext context) throws Exception {
Boolean testResult = context.getExecutionException().isPresent();
System.out.println(testResult); //false - SUCCESS, true - FAILED
}
}
#ExtendWith(RunnerExtension.class)
public abstract class Tests {
}
Taken from this answer:
JUnit5 - How to get test result in AfterTestExecutionCallback
So basically you override the standard behaviour -after- each assertion has been executed. In the case above you can add (when an exception is thrown --> take screenshot).
Here is the take a screenshot code for Selenium-Java:
WebDriver driver = new FirefoxDriver();
driver.get("http://www.google.com/");
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
// Now you can do whatever you need to do with it, for example copy somewhere
FileUtils.copyFile(scrFile, new File("c:\\tmp\\screenshot.png"));
Hope the above helps!
I've 4 test cases defined using TestNG within my Appium project and all 4 test cases performs almost same code execution besides the difference that all 4 test cases run on different parts of the app I'm automating. The issue I'm facing is within my test case I need to find an element and get its value which works fine in Test Case 1 but fails for Test Case 2, 3 and 4 respectively. However if I comment out Test Case 1, then the code works fine for Test Case 2 but fails for Test Case 3 and 4. If I run code for Test Case 1, 2, 3 or 4 individually, all of them work. I'm not able to understand why the code works only for the first test case in execution but fails to find the element in the next test case.
Note that the only option for me to find element is using absolute xpath value since the app I'm trying to automate does not have any other attribute defined.
Environment
java client 4.1.2
Appium server version: v1.7.2
Selenium: v3.4.0
Desktop OS/version used to run Appium if necessary: Windows 10 x64
Mobile platform/version under test: Fire TV Stick running on Android 5.1.1
Real device or emulator/simulator: Real device
Details
I've provided the code for Test1 below. As mentioned earlier, Test2, Test3 and Test4 are same as Test1. The code below is the one which fails from second Test onwards even though the code works fine when tested individually and the element is definitely present on the screen when the code is executed. However the script returns no element found.
Failing code
strTime1 = driver.findElementByXPath("/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout[1]/android.widget.FrameLayout/android.widget.FrameLayout[3]/android.widget.FrameLayout[3]/android.widget.FrameLayout[2]/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.TextView").getText();
Code To Reproduce Issue
#test //Test Case for Home tab
public void Test1_Home() throws InterruptedException, ParseException{
Thread.sleep(delay3); //Wait for 10 seconds to load the content
driver.findElementByXPath("//android.widget.FrameLayout[#content-desc="Home, Button"]").click(); //Code to click Home button
Thread.sleep(delay2); //Wait for 10 seconds to load the content
((AndroidDriver) driver).pressKeyCode(23); //Code to click first video thumbnail button
Thread.sleep(delay2); //Wait for 10 seconds to load the content
//Video pause verification code starts
((AndroidDriver) driver).pressKeyCode(23); //Pause the video
Thread.sleep(1000); //Wait for 1 seconds
strTime1 = driver.findElementByXPath("/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout[1]/android.widget.FrameLayout/android.widget.FrameLayout[3]/android.widget.FrameLayout[3]/android.widget.FrameLayout[2]/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.TextView").getText();
System.out.println(strTime1);
Thread.sleep(delay1); //Wait for 5 seconds
strTime2 = driver.findElementByXPath("/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout[1]/android.widget.FrameLayout/android.widget.FrameLayout[3]/android.widget.FrameLayout[3]/android.widget.FrameLayout[2]/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.TextView").getText();
System.out.println(strTime2);
time1 = time.parse(strTime1);
time2 = time.parse(strTime2);
System.out.println(time1);
System.out.println(time2);
if(String.valueOf(strTime1).equals(String.valueOf(strTime2)))
{
boolean result = true; //Set result to true
System.out.println("Home: Video playback pause successful");
Assert.assertTrue(result); //Passes the test case
}
else
{
boolean result = false; //Set result to false
System.out.println("Home: Video playback pause failed");
Assert.assertTrue(result); //Fails the test case
}
//Video pause verification code ends
Thread.sleep(delay2); //Allow the video to play for 10 seconds including buffering time
}
Exception stack traces
org.openqa.selenium.NoSuchElementException: An element could not be located on the page using the given search parameters. (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 10.13 seconds
Let me know if any further information is required. Any kind of help would be appreciated
could you please try to locate the element with relative xpath or accesability id?
Also it is always best practice to use latest versions of appium server and java client as they are continuously making changes to the appium.
below is the link for latest java client if you are using maven : https://mvnrepository.com/artifact/io.appium/java-client
This is an odd variety of a common problem.
I am running a Selenium project using a headless firefox browser.
I get the common NoSuchElementExceptions. That's nothing new. However, attempting to resolve them through explicit waits does not resolve the issue.
For example, the following line throws the NoSuchElementException:
WebElement trackingInbox = methodDriver.findElement(By.id("inbox-widget-container-id"));
I then add the following above this line:
FluentWait wait = new FluentWait(methodDriver);
wait.withTimeout(90, TimeUnit.SECONDS);
wait.pollingEvery(250, TimeUnit.MILLISECONDS);
wait.until(ExpectedConditions.presenceOfElementLocated(By.id("inbox-widget-container-id")));
WebElement trackingInbox = methodDriver.findElement(By.id("inbox-widget-container-id"));
In the first instance, I get the exception at the "methodDriver.findElement . . . ."
In the second instance I get it at the "wait.until . . . "
This happens when I wait for "presenceOf . . ." and when I wait for "visibilityOf . . ." The way it appears, the element has to be available before I wait for it, which appears to defeat the purpose.
The way it currently appears, I have no option but to add implicit waits, but I know there must be some way to do the explicit waits such that the element does not have to be available before I wait for it.
I wonder if there are any ideas as to what I am doing wrong and if there are any principles I can go by to determine whether a particular wait would be useful or not.
You have actually forgot to call ignoring function at the end, This ignoring is what you want. When you are waiting for visibility of the element, it might occur that element doesn't exist but If you use Ignoring function, it would ignore if such error happens until it meet with the given condition.
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, SECONDS)
.pollingEvery(5, SECONDS)
.ignoring(NoSuchElementException.class);
I am using Selenium WebDriver with multiple test steps which are divided as the following:
//Example Test Step 1
driver.get("https://url.de");
driver.findElement(By.id("login")).clear();
driver.findElement(By.id("login")).sendKeys("username");
driver.findElement(By.id("password")).clear();
driver.findElement(By.id("password")).sendKeys("password");
driver.findElement(By.cssSelector("#login-wrapper > input.button")).click();
driver.findElement(By.linkText("Your account")).click();
driver.findElement(By.cssSelector("button.link")).click();
driver.findElement(By.id("items_1")).click();
driver.findElement(By.id("items_2")).click();
driver.findElement(By.xpath("(//input[#id='items_1'])[1]")).click();
driver.findElement(By.xpath("(//input[#value='delete it'])[1]")).click();
driver.findElement(By.cssSelector("input.button.auth")).click();
System.out.println("[x] Test step has been performed sucessfully: ABO KUNDE");
If one test step fails, I want to catch this exception and force Selenium to continue with the next step. How can I handle this and do I have to define this handling for every single step?
So for example, the test step
driver.findElement(By.id("password")).sendKeys("password");
fails. Can I force Selenium to continue with "Example Test step 2"? We are using the Selenium WebDriver with BrowserStack.
I am using Selenium 3.4 with Java. With Chrome, everything works fine. But I need to use Firefox, and there something breaks.
I am automating the testing of a Dojo UI, and need to wait while the Dojo UI does a lot of rendering. So here is what I do, and it works just fine in Chrome. Note that an implicit wait of 20 seconds is normally set in my code.
driver.switchTo().defaultContent();
driver.switchTo().frame(driver.findElement(By.id("contentframe"))); // relying on implicit wait
driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
(new WebDriverWait(driver, 120)).
until(ExpectedConditions.elementToBeClickable(By.id("some_id")));
I have simplified the code so you don't see how the implicit wait is set back to 20 seconds. When the problem happens, it does not get there, anyway. The WebDriverWait causes an exception. The exception says TypeError: can't access dead object
There is a corresponding message from inside the wait:
May 16, 2017 3:36:11 PM org.openqa.selenium.support.ui.ExpectedConditions findElement
WARNING: WebDriverException thrown by findElement(By.id:
some_id)
org.openqa.selenium.WebDriverException: TypeError: can't access dead object
There is also some JavaScript error output, apparently, by geckodriver:
JavaScript error: chrome://marionette/content/listener.js, line 1555: TypeError: can't access dead object
*************************
A coding exception was thrown and uncaught in a Task.
Full message: TypeError: can't access dead object
Full stack: find_#chrome://marionette/content/element.js:284:7
element.find/</findElements<#chrome://marionette/content/element.js:255:15
implicitlyWaitFor/</elementSearch#chrome://marionette/content/element.js:600:15
implicitlyWaitFor/<#chrome://marionette/content/element.js:627:5
implicitlyWaitFor#chrome://marionette/content/element.js:593:10
element.find/<#chrome://marionette/content/element.js:254:24
element.find#chrome://marionette/content/element.js:253:10
findElementsContent#chrome://marionette/content/listener.js:1314:19
TaskImpl_run#resource://gre/modules/Task.jsm:319:42
TaskImpl#resource://gre/modules/Task.jsm:277:3
createAsyncFunction/asyncFunction#resource://gre/modules/Task.jsm:252:14
Task_spawn#resource://gre/modules/Task.jsm:166:12
TaskImpl_handleResultValue#resource://gre/modules/Task.jsm:389:16
TaskImpl_run#resource://gre/modules/Task.jsm:327:15
TaskImpl#resource://gre/modules/Task.jsm:277:3
createAsyncFunction/asyncFunction#resource://gre/modules/Task.jsm:252:14
Task_spawn#resource://gre/modules/Task.jsm:166:12
dispatch/<#chrome://marionette/content/listener.js:186:15
*************************
*************************
A coding exception was thrown and uncaught in a Task.
Full message: TypeError: can't access dead object
Full stack: find_#chrome://marionette/content/element.js:284:7
element.find/</findElements<#chrome://marionette/content/element.js:255:15
implicitlyWaitFor/</elementSearch#chrome://marionette/content/element.js:600:15
implicitlyWaitFor/<#chrome://marionette/content/element.js:627:5
implicitlyWaitFor#chrome://marionette/content/element.js:593:10
element.find/<#chrome://marionette/content/element.js:254:24
element.find#chrome://marionette/content/element.js:253:10
findElementsContent#chrome://marionette/content/listener.js:1314:19
TaskImpl_run#resource://gre/modules/Task.jsm:319:42
TaskImpl#resource://gre/modules/Task.jsm:277:3
createAsyncFunction/asyncFunction#resource://gre/modules/Task.jsm:252:14
Task_spawn#resource://gre/modules/Task.jsm:166:12
TaskImpl_handleResultValue#resource://gre/modules/Task.jsm:389:16
TaskImpl_run#resource://gre/modules/Task.jsm:327:15
TaskImpl#resource://gre/modules/Task.jsm:277:3
createAsyncFunction/asyncFunction#resource://gre/modules/Task.jsm:252:14
Task_spawn#resource://gre/modules/Task.jsm:166:12
dispatch/<#chrome://marionette/content/listener.js:186:15
Moreover, my automatic exception processing tries to take a screenshot but that fails with the very same error. The code line is:
File snapshotTempFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
And this time the output from geckodriver is:
A coding exception was thrown and uncaught in a Task.
Full message: TypeError: can't access dead object
Full stack: capture.viewport#chrome://marionette/content/capture.js:65:7
takeScreenshot#chrome://marionette/content/listener.js:1782:14
dispatch/</req<#chrome://marionette/content/listener.js:188:22
TaskImpl_run#resource://gre/modules/Task.jsm:319:42
TaskImpl#resource://gre/modules/Task.jsm:277:3
createAsyncFunction/asyncFunction#resource://gre/modules/Task.jsm:252:14
Task_spawn#resource://gre/modules/Task.jsm:166:12
dispatch/<#chrome://marionette/content/listener.js:186:15
So, can I do anything to make this work properly? And is this something I need to raise as a geckodriver bug?
The only thing I could google out is this: https://github.com/mozilla/geckodriver/issues/614 and the only proposed solution there is driver.switchTo().defaultContent() . This might fix my screenshot routine, but the element I am waiting for is inside the content frame, so I can't use this fix for the wait.
Not sure if this will help you but when I ran into this error message, I was able to get past it by having:
driver.switchTo().defaultContent();
driver.switchTo().frame(0);
between each interaction with an element in the iframe.
Example:
driver.switchTo().frame(0);
myPage.selectElement(getCycleSummary());
driver.switchTo().defaultContent();
driver.switchTo().frame(0);
myPage.selectDisplayedElement(this.getCycleBtn());
Without the driver switches I would receive the dead object error.
It looks like the frame is reloaded with a new reference while you are waiting for the element some_id.
I would classify this issue as a bug since the error returned by the driver is not defined by the WebDriver protocol.
Your best chance to make it work is probably to implement a custom waiter to locate the frame/element and skip unhandled exceptions:
WebElement elem = waiter.Until(elementToBeClickableInFrame(By.id("contentframe"),
By.id("some_id")));
public static ExpectedCondition<WebElement> elementToBeClickableInFrame(final By locatorFrame, final By locator) {
return new ExpectedCondition<WebElement>() {
#Override
public WebElement apply(WebDriver driver) {
try {
driver.switchTo().defaultContent();
driver.switchTo().frame(driver.findElement(locatorFrame));
WebElement elem = driver.findElement(locator);
return elem.isDisplayed() && elem.isEnabled() ? elem : null;
} catch (Exception e) {
return null;
}
}
#Override
public String toString() {
return "element located by: " + locator + " in " + locatorFrame;
}
};
}
See,
There Should be a format which i am giving below:
First switch to frame. (Switch to default first in case already you are in another frame).
Perform your action (click on any element)
Switch to default content again. (if you do not switch it back, it creates problem).
driver.switchTo().defaultContent();
driver.switchTo().frame(locator or name of the frame);
driver.click(your element locator);
driver.switchTo().defaultContent();