TestCafe fails to retrieve elements after appcues configuration is added - testing

I'm using TestCafe for all my web tests and things were working fine until some configuration files were updated in the web project with some app cues to work. Most of the tests fail but not all which makes it really tricky to figure out what is the problem.
Here is the problem:
A function that specifies a selector can only return a DOM node, an array of nodes, NodeList, HTMLCollection, null or undefined. Use ClientFunction to return other values.
Browser: Chrome 78.0.3904 / Mac OS X 10.14.6
47 | return Selector('div').withExactText('Project').nextSibling().find('div')
48 | .find(`${this.headLocator}.${Name}`);
49 | }
50 |
51 | async BreakDownCount(Name) {
> 52 | return helper.getIntFromString(await this.BreakdownLocator(Name).textContent);
Here is the code:
BreakdownLocator(Name) {
return Selector('div').withExactText('Project').nextSibling().find('div')
.find(`${this.headerLocator}.${Name}`);
}
async BreakDownCount(Name) {
return helper.getIntFromString(await this.BreakdownLocator(Name).textContent);
}
I have a feeling that it fails where I use async functions or promise as there are other tests that didn't fail but they don't have promise. I looked around and found this discussion but this didn't help. Any suggestions?

Related

Selenium request returns error 400 - Bad request

I'm trying to get pull data from http://43.248.49.97/indexEn
Normally on the browser there is a first request to the url above returns error 412, the second one is to a JS file and the third one is also to the url above and returns ok (200).
When using selenium the third request returns error 400 - Bad request instead.
I'm using Python. Any ideas on why this is happening?]
Thanks
I had the same problem with you but I found a solution which perfectly solves my problem.
Maybe your program fails because you are detected as a robot using selenium.
So here is the method to solve it or hide your identity(window.navigator.webdriver) by using JavaScript:
With CDP(Chrome Devtools-Protocol), you run the code before the frame is loaded by the JS file(detector). Therefore, use these codes to remove the "webdriver True" property:
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
})
key codes:
from selenium.webdriver import Chrome
driver = Chrome('D://chromedriver.exe')
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
"source": """
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
})
"""
})
driver.get('http://pythonlearner.com')
However, if you upgrade your Chrome to 88 right now. The method mentioned above will be useless. Fortunately, we still have a solution (add this code)
chrome_options.add_argument("--disable-blink-features=AutomationControlled")
These codes should help you pass the JS file so that you can obtain the data. At least I successfully run my program.
I am using ChromeDriver 104.0.5112.79.0 and the solution with chrome_options.add_argument("--disable-blink-features=AutomationControlled") works for me!

Karate UI cross browser examples

Does someone have any examples of how to run cross browser UI tests in karate? I know from Peter's twitter feed that its possible but anyone having some examples?
Thanks
Look at this example: test-01.feature
It is a Scenario Outline and each row changes the value of * configure driver = config, see the Examples at the end:
Examples:
| config |
| { type: 'chrome' } |
| { type: 'chromedriver' } |
| { type: 'geckodriver' } |
Another strategy could be to re-run the test with different values of karate.env or use call and loop over a second feature file.

running javascript functions using wallaby's execute_script does not work

System
OSX v10.13.4 / Elixir v1.6.5 / OTP 19 / Phoenix 1.3.2 / Wallaby 0.19.2 / PhantomJS 2.1
Issue
The following code works in testing
execute_script(session, "localStorage.setItem('test', 'foo'); return localStorage.getItem('test');")
However, if I call the exact same methods which are in a function called get_test() inside app.js of my Phoenix App
function get_test() {
localStorage.setItem('test', 'foo');
return localStorage.getItem('test');
}
window.get_test = get_test
And run the following in my test suite
execute_script(session, "return get_test();")
I get {:error, :obscured}
I have tried with selenium on the same code and it works. However, for some reason, with PhantomJS it does not seem to find functions that have been created by ourselves.
Am I missing something? I did notice in the tests for execute_script in wallaby there are no tests that call specifically created functions.
https://github.com/keathley/wallaby/blob/master/integration_test/cases/browser/execute_script_test.exs
A similar test
https://github.com/keathley/wallaby/blob/master/integration_test/cases/browser/local_storage_test.exs
of which I added the following to the local_storage_test to verify I was not going nuts
#function_script """
function get_tester() {
localStorage.setItem('tester', 'foo');
return localStorage.getItem('tester');
}
return get_tester();
"""
session
|> visit("index.html")
|> execute_script(#function_script, fn(value) -> send self(), {:callback, value} end)
assert_received {:callback, "foo"}
and it passed. This is clearly something wrong with my app. Or Phantom config perhaps.
UPDATE:
Although not mentioned directly - I have narrowed this down to libsodim not loading properly with phantomjs. Back to basics on the debugging. Nothing wrong with the JS written. On a positive note, I now have a whole library of tests which is cool and some cool tools for testing.

Leadfoot + sauce: mapping a collection of elements using getAttr fails in mobile only

My use case varies for this, but in general i'm trying to collect a bunch of elements and then apply _.map() to each. The problem is that this series of .getAttribute() calls can cause a test that works locally to fail against a remote server like sauce/android.
One example: collecting all <div class='article'><a href='articles/{id}'> on a page and then getting the hrefs. it might look something like this, and this approach will work until i test on a mobile (android) sauce environment. then I get a timeout.
Is it possible this is an issue related to my android environment capabilities? To piling up so many requests? I've tried scaling my test down from using 75 articles to only 45 and i've upped the timeout to 60s and still the mobile test fails. locally with chromedriver is fine, chrome desktop + sauce is fine.
Not my actual test but an approximation of the code i'm talking about:
/// ... return this.remote
.findAllByTagName('div.article a')
.then(function (articles) {
var promises = articles.map(function(article) {
return article.getAttribute('href');
});
Promise.all(promises)
.then(function (hrefs) {
uniques = _.uniq(hrefs);
assert(hrefs.length === uniques.length);
});
});
Since you're seeing a timeout error, I'd suggest continuing to increase the test timeout until the test passes. The mobile testing environments on Sauce are both slower to initialize and slower to operate than the desktop environments, so it's quite possible that a test with many requests is simply very slow.
One way to speed things up would be to use an execute block to gather the references, like:
.then(function (articles) {
return this.parent.execute(function (articles) {
return articles.map(function (node) {
return node.getAttribute('href');
});
}, [ articles ]);
})
In the above snippet, the articles element array is passed as an argument to the execute block. The remote WebDriver will deserialize the element references into actual DOM elements that can be operated on in the execute code. This is significantly more efficient than using individual getAttribute requests for each element since only a single request will be made to the remote browser.

Access window object / browser scope from protractor

I'm running tests with protractor, but it seems impossible to access the JS 'window' object. I even tried adding a tag in my html file that would contain something like
var a = window.location;
and then try expect(a) but I couldn't make it work, I always get undefined references...
How should I process to access variables that are in the browser scope ?
Assuming you are using a recent version of Protractor, let's say >= 1.1.0, hopefully >= 1.3.1
Attempting to access Browser side JS code directly from Protractor won't work because Protractor runs in NodeJS and every Browser side code is executed through Selenium JsonWireProtocol.
Without further detail, a working example:
browser.get('https://angularjs.org/');
One-liner promise that, as of today, resolves to '1.3.0-rc.3'
browser.executeScript('return window.angular.version.full;');
You can use it directly in an expect statement given Protractor's expect resolves promises for you:
expect(browser.executeScript('return window.angular.version.full;')).
toEqual('1.3.0-rc.3');
Longer example passing a function instead of a string plus without expect resolving the promise for you. i.e. for more control and for doing some fancy thing with the result.
browser.driver.executeScript(function() {
return window.angular.version.full;
}).then(function(result) {
console.log('NodeJS-side console log result: ' + result);
//=> NodeJS-side console log result: 1.3.0-rc.3
});