Does capybara "within" deal with ajax, why failed within the css with the error " unable to find find css " - cucumber

I have a step like this:
Then(/^I can see the Eligible Bugs list "([^"]*)"$/) do |bugs|
bugs_list = bugs.split(", ")
assert page.has_css?(".eligible-bugs", :visible => true)
within(".eligible-bugs") do
bugs_list.each do |bug|
assert page.has_content?(bug)
end
end
end
But the step fail sometimes at the " within(".eligible-bugs") do" with the error 'Unable to find css ".eligible-bugs"'
I feel it is odd.
for the assertion has been passed. it means the css is visible.
why within cannot find css? How it happen.
But the step fail sometimes at the " within(".eligible-bugs") do" with the error 'Unable to find css ".eligible-bugs"'
I feel it is odd.
for the assertion has been passed. it means the css is visible.
why within cannot find css? How it happen.
BTW, I have set my max wait time to 5.
Capybara.default_max_wait_time = 5

The only way that should happen, is if the page is dynamically changing while you're running the test - sometime during your check for all bugs content on the page it is changing and the '.eligible-bugs' element is going way. The test and the browser run separately, so how/why it is happening depends on what else your page is doing in the browser, it would also depend on what steps have come before this in the test.
Also, note that it's not necessarily disappearing between the has_css? and the within statement first running. If it disappears at any point during the code inside the within running it could throw the same error as it attempts to reload the '.eligible-bugs' element.
From the title of the question I assume the list that you want to check is the result of a search or filtering action. If it is, does that action remove the existing '.eligible-bugs' element and then after some time replace it with a new one returned from an ajax request or something? If that is the case then, since you control the test data, you should be waiting for the correct results count to show, thereby ensuring any element replacements have completed, before checking for the text. How you do that would depend on the exact makeup of the page, but if each eligible bug was a child of '.eligible-bugs' and had a class of '.eligible-bug' I would write your test something like
Then(/^I can see the Eligible Bugs list "([^"]*)"$/) do |bugs|
bugs_list = bugs.split(", ")
assert_css(".eligible-bugs > .eligible_bug", count: bugs_list.size) # wait until the expected number of results have shown up
within(".eligible-bugs") do
bugs_list.each do |bug|
assert_content(bug)
end
end
end

Related

Failure to exit possible repaint issue

My strategy is set to process_orders_on_close=true. Everything else default.
The strategy sends alerts on entry and exit, and they are all coming at the correct moment.
However, on the chart itself, the strategy exits don't always show at the right point.
I am using a trail stop of $0.04 which is 4 ticks, that activates when a specified price level is hit.
For example, in CL1!, I just had a short that was supposed to activate a trail stop exit if the price hit $86.35 on the 5 minute chart. The price got down to $86.32 and then in the same candle, it closed at $86.43.
The position should have exited at $86.36 since that is $0.04 above the low.
The alert came correctly at $86.36. However, the chart never indicated that the order was exited, and it didn't reflect in the list of trades. However, if I turn off the strategy, and then turn back on, then it shows correctly.
This issue has happened several times, and the strategy exit shows up several candles later with what seems to be no rhyme or reason. Nothing related to the trail stop or my stop loss either.
Below is my code for the exit:
strategy.exit(alert_profit="WIN", alert_loss="LOSS", id="Exit", from_entry="Long", qty=1, limit=ltp, stop=lsl, comment_profit = "TP-Long "+str.tostring(ltp), comment_loss = "SL-Long "+str.tostring(lsl))
strategy.exit(alert_profit="WIN", alert_loss="LOSS", id="Exit", from_entry="Short", qty=1, limit=stp, stop=ssl, comment_profit = "TP-Short "+str.tostring(stp), comment_loss = "SL-Short "+str.tostring(ssl))
Both of these lines are contained within IF statements that check to see if a trailstop is set. Otherwise, it will use a different type of exit.

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.

Terminating each() block in Protractor

I was automating the an application (using Protractor) and I have come across situation where I wanted to select the an option from the type ahead using the DOWN arrow button from the Keyboard. Here is how I am approaching to this action.
After typing part into the text field I am getting the reference of each option that appear in the type ahead.
Now, I am using .each() method of protractor to iterate through each of the option to look for the required option.
I'm making the script to hit DOWN arrow button to iterate through each option in the type ahead.
Suppose there are 10 options displayed in the type ahead and the option that I need to select is at 5th position. Now when I reach the 5th position I am selecting the option but each() function still continues.
I want the loop to terminate when required option is selected. Something like BREAK statement in FOR loops.
BTW I have tried the above scenario with FOR loop but unable to use BREAK statement within then() handler.
Please let me know how to cope up with this situation.
You could throw an exception to terminate the loop. Put the loop inside try and use catch to wrangle your results. You can also just use a boolean variable to indicate that you have found a match and ignore everything after that point. I would just use a for loop though.
Edit:
You could add a variable to hold an action before the allBenchmarks.each
var action
Then inside the test
if(dataValue == optionToSelect){
action = function() {benchmark.click(); ...}
}
After the loop exits call the action
if (action) action()

Node-based automated testing of browser key events

I'm trying to write automated tests for Hashify Editor. Here are the sorts of assertions I'd like to make:
Assert that a textarea matches a particular selector.
Assert that the textarea is currently empty.
Type "_" into the textarea. Assert that it now contains __, and that the caret is positioned between the two underscores.
Type "hello" into the textarea. Assert that it now contains _hello_, and that the caret is positioned before the second underscore.
Type "_" into the textarea. Assert that it still contains _hello_, and that the caret is now positioned after the second underscore.
I've spent the day playing with Soda and Zombie.js, trying to get this work in either. I've managed to get close with Soda:
soda = require 'soda'
browser = soda.createClient ...
browser
.chain
.session()
.open('/')
.typeKeys('editor', '_')
.assertValue('editor', '__')
This assertion success, but the following doesn't:
.typeKeys('editor', 'hello')
.assertValue('editor', '_hello_')
# ERROR: Actual value '__' did not match '_hello_'
Using .type fails in a different manner:
.type('editor', 'hello')
.assertValue('editor', '_hello_')
# ERROR: Actual value 'hello' did not match '_hello_'
The suggestion on #275 of assaf/zombie got my hopes up, but I wasn't able to trigger the textarea's keypress handler using this approach.
Perhaps I'm going about this in the wrong way. Has anyone had success testing keypress handlers using Node? What's the best tool for the job?

Resources