I am testing a website that has a page that will update 4-5 minutes after I have done a certain action.
Here's what I've thought of:
Thread.sleep()/Continuously refreshing page waiting for update. This means my tests automatically get an additional 5 minutes added on.
I have a set of tests that are ordered by DependsOnMethod in a lengthy list. I could depend the first test on the test that performs the action, and have the second test depend on the last test to run. This option is not as bad...but it means putting the methods in a class that is completely irrelevant (and dependencies that don't make logical sense)
Are there any other options?
Note: I am using TestNG with WebDriver
Best solution would be to use implicit or explicit waits but it depends how the page update looks like. But if it's for instance some element with counter, you should try something like.
WebElement myDynamicElement = (new WebDriverWait(driver, 5 * 60)) //time in seconds
.until(ExpectedConditions.textToBePresentInElement(By.id("id"),
"Text after update"));
Related
I am doing something like this in Java Selenium (Numbers within parenthesis are line numbers. They are not in the actual code.)
(1) driver.get(URL1);
(2) driver.findElement(By.xpath(xpath)).click();
(3) WebDriverWait wait = new WebDriverWait(driver, 15);
(4) wait.until(webDriver -> ((JavascriptExecutor) driver).executeScript("return document.readyState").toString().equals("complete"));
(5) driver.get(URL2);
But 5 driver.get(URL2); is ignored when executing this code but if I step (debug) through these lines it works fine.
I added two lines like this
System.out.println(new Date());
before 3 and after 4 and the result was weird:
When running the program "normal" these printouts always return at the same time. In other words, the wait is returning within 1 second. However, when debugging and stepping through these lines, there is a 4-5 second long delay between these timestamps, even if I step as fast as I can.
I suspect that 3-4 that is supposed to verify that the page has loaded are executed so fast so that they check the state of the previous (current) page (URL1) rather than waiting for the page resulting from the click. And then the browser is busy loading a new page and therefore can't handle the command sent in 5.
How do I fix this?
I have read dozens of questions here on SE on how to make Selenium wait for a page to load but I am already using one of the most common solutions (line 3-4) suggested in these questions.
I have worked with Selenium and Web driver in Python for some time. I have just used the delay() method in Python for a rest. Can you upload the whole code or something to try to find out how to help you? Thanks!
We have many e2e test written by Selenide.
To avoid failing test in test server, I would like selenide to wait for html element appearing.
I know some scripts like wait.until(...) for this. But, I don't want to fix all test code.
Is there any global switch or setting for Selenide ? ( in detail, I hope the option making cssselector waiting )
My question is resolved by this post
Implicit Wait is the way to configure the WebDriver instance to poll the HTML DOM (DOM Tree)
for a configured amount of time when it tries to find an element
or find a group/collection of elements if they are not immediately available.
As per the current W3C specification the default time is configured to 0.
We can configure the time for the Implicit Wait any where within our script/program and can reconfigure it as per our necessity.
Once we set Implicit Wait it will be valid for the lifetime of the WebDriver instance.
I think implicit wait time is almost the global switch I expected.
Before performing any action, selenide provides methods to look up for Conditions.
$("By Locator").shouldBe(Condition."Desired Condition").
I might be late for this question. But for anyone who still needs help in selenide wait, my answer might still be helpful.
For selenium if you have wait method like:
element = (new WebDriverWait(driver, <timeOutForElement>))
.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(<cssSelector>)));
You can perform the same in Selenide with element = $(<cssSelector>).should(exist);
For
element = (new WebDriverWait(driver, <timeOutForElement>))
.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(<cssSelector>)));
We just go with element = $(<cssSelector>).shouldBe(visible);
Reference Page Here.
I'm fairly new to Selenium and I'm writing a test for a web app using it. In doing this, I'm using assertions to make sure the web app is working correctly. For a few of these assertions, I'm asserting on a web element that has a numeric value in which the expected number is known. The problem is when a change is made that changes this numeric value the change happens gradually based on how fast the internet connection is. Up to this point have resorted to using sleep's to wait for the element to finish refreshing before I use assertions but I would like to make it so this wait is no longer than the time it takes for the element to stop refreshing and thus not have to include sleep's that are either too short or too long.
You should try this:
WebDriverWait wait = new WebDriverWait(webDriver, timeoutInSeconds);
wait.until(ExpectedConditions.visibilityOfElementLocated(<specific locator of element>));
Sleep is not a good option because you wait always expected the amount of time.
In the approach presented above you always wait for the visibility of a specific element. When an element is visible your test steps will go forward. There is no extra wait time which you got with implicit sleep
Avoid using sleep and replace it with an implicit wait or use expected condition if applicable. below is c# code for it
int time =10; // set maximum time required for operation
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(time));
wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementIsVisible(By.XPath(""))); //replace "" with your desired xpath
The above code will wait for max 10 seconds for an element to be visible. but if it appears earlier then it will jump to next process so you need not have to wait for a specific time. Also, there are other expected conditions available like ElementExists, ElementToBeClickable etc. I will leave it to you to explore the appropriate option for yourself
if you wan t to use implicit wait specifically use below code
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(50));
I am new to selenium webdriver (java coding). I have been given a website and asked to write script to check if all the pages load properly.I was not sure how to check a page load. One of my friend suggested that when a page load, i should look for last element which gets loaded and use a wait method on that element to check until its visible.
My question is I have more than 50 pages to check. For each page should i use a wait method and check visibility, becoz it takes a lot of time . Is there any other way?
You can solve the issue by following the steps given below (for all 50 pages, one at a time):
Identify an element which is displayed at last in the browser rendering.
Add visibility_of_element_located, to check whether the element is displayed on the web page or not.
Wait for visibility of an element:
element = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.ID, "myDynamicElement")) # here, you can use any available locator of your choice, like, By.XPATH, BY.CLASS_NAME etc.
This waits up to 10 seconds before throwing a TimeoutException or if it finds that the element is displayed, will return it in 0 - 10 seconds. WebDriverWait by default calls the ExpectedCondition every 500 milliseconds until it returns successfully. A successful return is for ExpectedCondition type is Boolean return true or not null return value for all other ExpectedCondition types.
So, you are not actually waiting for 10 seconds to check whether the element is displayed. Once the element is displayed on the page, the method will return immediately within 10 seconds.
Note: 10 seconds is configurable.
You need to look in visual testing direction, and pure selenium not designed for that.
You may try two addons for Selenium:
1) Applitools (https://applitools.com/), cloud based, you could try it for free,
examples is here https://eyes.applitools.com/app/Web/Deploy/Tutorial/tutorial.html
2) Or you could use Sikuli(http://www.sikuli.org/), free, non cloud.
I am using selenium to do the UI automation for a web application.
1) My doubt is
when i use the click() method like, right_btn.click() whether it just clicks the right_btn and comes out or it just waits for the underlying actions to be completed before it moves out???
bcoz i read this
When i googled for WebElement.click() http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/WebElement.html it says like, it gets blocked whenever the click() involves opening a new page but here it doesnt opens a new page rather it involves in service call.
2) What i actually want to know?
I want to know this actually to calculate the latency involved in carrying out each actions in the UI. Is there any way to calculate the latency for each UI actions, just like we can see the latency time when we use inspect element in chrome. Thanks in advance.
In java, you can make a Date a = new date() object with the current time, just before your right_btn.click() and then wait for the resulting page to open, (if in a new tab/window - switch to it) and then find some element on that page
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(
ExpectedConditions.visibilityOfElementLocated(By.id("someid")));
After that returns the element, make another Date b = new Date()
The latency is the difference in milliseconds int millis = b-a;
Yes, a small part of that total time is Selenium searching for the 2nd element, but I'm afraid this might be the best you can do with java/selenium for your purpose.
I am not too sure if I understood your question exactly
How to calculate Latency is hard , but for intercepting calls you can use browserMobProxy in your code and check if particular call is complete and move on