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
Related
I am locating elements by Findby and then using a wait function to throw an error if the element doesn't exist but appium gets stuck searching for the elements and keeps giving nosuchelementerror infinitely
here is my code:
#FindBy(id = "tv_error_card")
MobileElement NID_Card_Error;
WebDriverWait wait = new WebDriverWait(driver, 5000);
if(wait.until(ExpectedConditions.visibilityOf(NID_Card_Error)) == null) {
System.out.println("time expired");
assertTrue("element messing ", false);
}
I know I can use wait with a by locator but I am trying to do it with mobile element
Its working as expected only. visibilityOf condition is looking for the element for the given time and throwing NoSuchElementException if not found. You need to catch the exception and perform the steps what you need. You need to use try-catch like below,
try {
wait.until(ExpectedConditions.visibilityOf(NID_Card_Error));
} catch (org.openqa.selenium.NoSuchElementException e) {
System.out.println("time expired");
assertTrue("element messing ", false);
}
How can I make the selenium driver in Java wait on nothing for a few seconds, just to pause the driver?
Simply do Thread.sleep(1000) to sleep for 1 second.
There are different ways to wait using selenium:
Explicit Waits: wait for a certain condition to occur before proceeding further in the code
WebDriver driver = new FirefoxDriver();
driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = (new WebDriverWait(driver, 10)).until(ExpectedConditions.presenceOfElementLocated(By.id("myDynamicElement")));
This waits up to 10 seconds before throwing a TimeoutException or if it finds the element will return it in 0 - 10 seconds
Implicit waits: An implicit wait is to tell WebDriver to poll the DOM for a certain amount of time when trying to find an element or elements if they are not immediately available.
WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = driver.findElement(By.id("myDynamicElement"));
Also you can use Thread.sleep(), this is not recommended but if you are just debugging this is the easiest way.
You can take a look to the Selenium documentation to understand better how to use waits.
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Seemed to do the trick.
fun WebDriver.delay(timeout: Duration) {
val until = System.currentTimeMillis() + timeout.toMillis()
WebDriverWait(this, timeout).until {
return#until until <= System.currentTimeMillis()
}
}
It's kotlin extendsions code. normally method like this:
fun delay(driver: WebDriver, timeout: Duration) {
val until = System.currentTimeMillis() + timeout.toMillis()
WebDriverWait(driver, timeout).until {
return#until until <= System.currentTimeMillis()
}
}
This is what I'm using in Python
import time
print "Start : %s" % time.ctime()
time.sleep( 5 )
print "End : %s" % time.ctime()
Output :
Start : Tue Feb 17 10:19:18 2009
End : Tue Feb 17 10:19:23 2009
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")));
I have a large flows in my project. I am automating these flows using selenium if I get an any error in 99th step consisting of 100 steps then I need to start from first step.
So is there any thing to pause/continue selenium script even though if locator not found.
public void waitForElementToBeVisible(String cssSelector) throws Throwable {
try {
WebDriverWait wait = new WebDriverWait(driver, 30); //30 = TIMEOUT DURATION IN SECONDS
wait.until(ExpectedConditions.or(
ExpectedConditions.visibilityOfElementLocated(By.cssSelector(cssSelector)) //CSS SELECTOR CAN BE DEFINED WHEN THIS METHOD IS CALLED e.g. waitForElementToBeVisible("Button");
));
} catch (Exception e) {
System.out.println("Timeout exceeded");
//ACTIONS YOU WANT TO CARRY OUT IF THE ELEMENT CAN'T BE FOUND, COULD JUST BE NOTHING.
}
}
alternatively, if you want to run this within your test, without setting up a method, simply do the following....
try {
WebDriverWait wait = new WebDriverWait(driver, 30); //30 = TIMEOUT DURATION IN SECONDS
wait.until(ExpectedConditions.or(
ExpectedConditions.visibilityOfElementLocated(By.cssSelector("Button")) //CSS SELECTOR CAN BE DEFINED WHEN THIS METHOD IS CALLED e.g. waitForElementToBeVisible("Button");
));
} catch (Exception e) {
System.out.println("Timeout exceeded");
//ACTIONS YOU WANT TO CARRY OUT IF THE ELEMENT CAN'T BE FOUND, COULD JUST BE NOTHING.
}
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.