Make Watir-webdriver to load a page for limited time and to be able to retrieve information later - watir

I know that there are several questions related to implementation of waiting and timeouts in Watir, however I have not found an answer to my problem (which must be common). I use Watir-webdriver for testing of a page that due to AJAX implementation loads portion-by-portion for very long time (more than 5 min). I need to be able just to sample this page for a limited time (20-40 sec) and to be able to analyze the information that is loaded during this short time. However, as I know, there is no straightforward direct mechanism to tell Watir::Browser to stop. I can use the Timeout, but although my script gets the control after rescue, it is impossible to interrogate the browser and verify the information that it is able to received during the timeout window. All I can do at this point is to kill the process and restart the browser as discussed here: Make headless browser stop loading page and elsewhere.
The code below illustrates my situation. In this example I have a global timeout (30 sec) and a local timeout (15 sec) used for reading the page. It never gets to b.text call; the script just outputs the first exception after 15 sec and then it keeps waiting for the browser to be released and after the global timeout of 30 sec prints the second exception message.
Time out. Got into exception branch
Dropped to bottom rescue.
The end.
I also tried to send an 'escape' key to the browser, but any communication with it while it is in the goto method is impossible. Any tips and suggestions will be appreciated!
require 'watir-webdriver'
require 'timeout'
client = Selenium::WebDriver::Remote::Http::Default.new
client.timeout = 30 # Set the global timeout
b = Watir::Browser.new :chrome, :http_client => client
my_url = '...here is my address...'
begin
begin
Timeout::timeout(15) { b.goto my_url } # Access the page with local timeout
b.close # if all is unbelievably good and the page is loaded
rescue Exception => e
puts 'Time out. Got into exception branch'
if b.text.include? 'my_text' # NEVER GETS HERE
puts 'Yes, I see the text!'
else
puts 'I do not see the text.'
end
end
rescue Exception => e
puts 'Dropped to bottom rescue.'
end
puts 'The end.'

Watir relies on Selenium WebDriver to handle calls to the browser. At this time all browsers require that the document.readyState of the current frame return "complete" before returning control to your code.
A recent update to the webdriver specification appears to allow for the possibility of a browser driver implementing a page loading strategy that is not blocking, but it is not a requirement and is not supported at this time.
https://w3c.github.io/webdriver/webdriver-spec.html#the-page-load-strategy

Related

What is Comunication Failure in Shopware 5?

when creating new theme there's error occurred.
0 - Communication Failure
Why this happen? could you please help me?
This usually happens due to a timeout that occurs when the Theme-controller tries to read the Theme's configuration for the first time. Unfortunately, this is quite a resource-heavy process; on weaker servers, timeouts may occur during this process quite often.
You can confirm this by opening the Theme-Manager, opening your browser's developer tools, refreshing the Theme overview and look at the response of the backend/Themes/list-Request.
You can give your server more time with the php-function set_time_limit. In engine/Shopware/Components/Theme/Installer.php, in the synchronize-method, prepend set_time_limit(0):
public function synchronize()
{
set_time_limit(0);
$this->synchronizeThemes();
}
Alternatively, prepend set_time_limit(0); to your shopware.php file, but don't forget to remove it again once the theme-overview loaded successfully.

Random failure of selenium test on test server

I'm working on a project which uses nodejs and nighwatch for test automation. The problem here is that the tests are not reliable and give lots of false positives. I did everything to make them stable and still getting the errors. I went through some blogs like https://bocoup.com/blog/a-day-at-the-races and did some code refactoring. Did anyone have some suggestions to solve this issue. At this moment I have two options, either I rewrite the code in Java(removing nodejs and nightwatch from solution as I'm far more comfortable in Java then Javascript. Most of the time, struggle with the non blocking nature of Javascript) or taking snapshots/reviewing app logs/run one test at a time.
Test environment :-
Server -Linux
Display - Framebuffer
Total VM's -9 with selenium nodes running the tests in parallel.
Browser - Chrome
Type of errors which I get is element not found. Most of the time the tests fail as soon the page is loaded. I have already set 80 seconds for timeout so time can't be issue. The tests are running in parallel but on separate VM's so I don't know whether it can be issue or not.
Edit 1: -
Was working on this to know the root cause. I did following things to eliminate random fails: -
a. Added --suiteRetries to retry the failed cases.
b. Went through the error screenshot and DOM source. Everything seems fine.
c. Replaced the browser.pause with explicit waits
Also while debugging I observed one problem, maybe that is the issue which is causing random failures. Here's the code snippet
for (var i = 0; i < apiResponse.data.length; i++) {
var name = apiResponse.data[i];
browser.useXpath().waitForElementVisible(pageObject.getDynamicElement("#topicTextLabel", name.trim()), 5000, false);
browser.useCss().assert.containsText(
pageObject.getDynamicElement("#topicText", i + 1),
name.trim(),
util.format(issueCats.WRONG_DATA)
);
}
I added the xpath check to validate if i'm waiting enough for that text to appear. I observed that visible assertion is getting passed but in next assertion the #topicText is coming as previous value or null.This is an intermittent issue but on test server happens frequently.
There is no magic bullet to brittle UI end to end tests. In the ideal world there would be an option set avoid_random_failures=true that would quickly and easily solve the problem, but for now it's only a dream.
Simple rewriting all tests in Java will not solve the problem, but if you feel better in java, then I would definitely go in that direction.
As you already know from this article Avoiding random failures in Selenium UI tests there are 3 commonly used avoidance techniques for race conditions in UI tests:
using constant sleep
using WebDriver's "implicit wait" parameter
using explicit waits (WebDriverWait + ExpectedConditions + FluentWait)
These techniques are also briefly mentioned on WebDriver: Advanced Usage, you can also read about them here: Tips to Avoid Brittle UI Tests
Methods 1 and 2 are generally not recommended, they have drawbaks, they can work well on simple HTML pages, but they are not 100% realiable on AJAX pages, and they slow down the tests. The best one is #3 - explicit waits.
In order to use technique #3 (explicit waits) You need to familiarize yourself and be comfortable with the following WebDriver tools (I point to theirs java versions, but they have their counterparts in other languages):
WebDriverWait class
ExpectedConditions class
FluentWait - used very rarely, but very usefull in some difficult cases
ExpectedConditions has many predefinied wait states, the most used (in my experience) is ExpectedConditions#elementToBeClickable which waits until an element is visible and enabled such that you can click it.
How to use it - an example: say you open a page with a form which contains several fields to which you want to enter data. Usually it is enought to wait until the first field appears on the page and it will be editable (clickable):
By field1 = By.xpath("//div//input[.......]");
By field2 = By.id("some_id");
By field3 = By.name("some_name");
By buttonOk = By.xpath("//input[ text() = 'OK' ]");
....
....
WebDriwerWait wait = new WebDriverWait( driver, 60 ); // wait max 60 seconds
// wait max 60 seconds until element is visible and enabled such that you can click it
// if you can click it, that means it is editable
wait.until( ExpectedConditions.elementToBeClickable( field1 ) ).sendKeys("some data" );
driver.findElement( field2 ).sendKeys( "other data" );
driver.findElement( field3 ).sendKeys( "name" );
....
wait.until( ExpectedConditions.elementToBeClickable( buttonOK)).click();
The above code waits until field1 becomes editable after the page is loaded and rendered - but no longer, exactly as long as it is neccesarry. If the element will not be visible and editable after 60 seconds, then test will fail with TimeoutException.
Usually it's only necessary to wait for the first field on the page, if it becomes active, then the others also will be.

How can I make .goto non-blocking?

I'm writing a rails app which fetches text from an HTML page using Watir and Chrome Headless. All good so far!
The problem starts when I request a page which has a long load time to completely load all elements despite the fact that I don't need them.
Current code I use:
browser = Watir::Browser.new :chrome, headless: true
browser.goto(url)
The .goto function call, however, blocks until ALL elements have loaded. That's not really what I need - what I need is for goto to just start fetching the page, then continue running code since I really just want to wait until the text I need is present, then fetch it.
Any ideas?
Goto will not leave the control until 60 seconds, If page load time exceeds 60 seconds, then it would throw the error. And also Watir.default_timeout has nothing to do with Goto's page loading. You need to set the timings for page_load which you can do by directly calling selenium driver as I have done below because Watir hasn't offered any systax for that
Write the below code, you could achieve what you want
begin
b.driver.manage.timeouts.page_load=5
b=Watir::Browser.new
b.goto(url)
rescue #I have written the rescue block here because goto will the error for you If page is not loaded within a given time
end
AND THEN you can write your rest of the code here, for an example,
puts b.span(text: 'something').text
What happens here is, goto will be block the execution of the code followed by goto for 5 seconds, and then it would fall into the rescue block, so program would continue to execute next line as you expected.
With the new w3c webdriver specification, you can set the page load strategy to 'none.' https://w3c.github.io/webdriver/webdriver-spec.html#navigation
Only Firefox and IE might have this implemented already.

ServiceStack RequestLogger shows past requests as "is running" long after being issued

I am running ServiceStack 3.97 and just added the RequestLogger plugin - amazing that it is built-in, just what I needed. The worrisome thing I noticed once I tried it is that it says all the previous GET requests have "is running = true".
For example, I issued a few requests in a browser tab (pressing F5 a few times, and closed tab) and can see them show up here /api/requestlogs. In the items column, the elapsed time keeps ticking each time I refresh and is running is always true.
This is very scary as it appears to be saying that the requests remain open. If so, it could be related to an unknown error I get over time whereby SS is unable to return an Open connection.
Here is a sample of the items field:
_request Duration Stopwatch
is Running true
elapsed PT8M31.5460178S
elapsed Milliseconds 511546
elapsed Ticks 1395611107
Any suggestions or ideas as to why this is happening and/or how to dig deeper? What would keep GETs open?
The RequestLogger takes a 'snapshot' which includes a dump of the Request.Items dictionary (which contains a Stopwatch) into a rolling log of DTO's, but this doesn't keep the request 'open' as you might think, so there's no need for concern.

How does the .Exist timeout work within QTP?

I've worked with the .Exist method quite a bit, but I recently moved to a new project (now using a WPF application) with QTP 11 (whereas previously I had QTP 10).
Now I'd like to check that a message does not exist by using object.Exist(2). Weirdly, I only get a result after ~23 seconds, instead of the 2 seconds I was expecting.
How does the timeout work? In previous projects, using object.Exist(2) would wait 2 seconds before determining that the object didn't exist. The QTP help file also says it should only wait for 2 seconds (the specified timeout parameter).
Now, it seems as though it's waiting for the Timeout Parameter (2 seconds) AND Object Synchronization Timeout (20 seconds).
Also, Smart Identification is disabled, so it shouldn't be waiting for that. Highlighting the object using the Object Repository instantly says the object doesn't exist.
Has the timeout behavior changed between QTP v10 and v11?
Why does it take so long to say an object doesn't exist?
The Exist method does not work for the last object only.
It works hierarchically - which means this method checks each parent object before checking the last one.
The timeout only works for the last object.
if you want to receive the answer immediately, I suggest you use the following code-
if WPFWindow("x").Exist(0) Then
if WPFWindow("x").WPFButton("y").Exist(0) Then
'action
End if
End if
Make sure you don't have "Smart Identification" enabled for the test object in the Object Repository. That can get in the way.
The additional time that you're encountering is the default timeout setting, which is set to 20 seconds by default. Any Wait or Exist timers will stack on top of the default timeout.
It can be changed in the test settings:
Test Settings > Run > Object synchronization timeout - set in seconds
or in the vbscript:
Setting("DefaultTimeout") = 4000 'set in milliseconds
Using DefaultTimeout function at the beginning of the driver script would be sufficient .
Setting("DefaultTimeout") = 10000 'set in milliseconds
If any object exceeds the timeout limit of 10 seconds as mentioned above then the object will fail to get captured and Run Results will show a failure
I would recommend going by with just the default timeout. Using .Exist(x) will use the mentioned time for each child.

Resources