Cypress scrollIntoView() giving error while assertion - selenium

while I using should('be.visible') assertion then if the element is not on the screen assertion is giving an error. So that's why I using scrollIntoView() but this time element comes on screen so scrollIntoView() cannot work as respected an giving error too.
I don't want to use 'exist' i need to use 'be.visible' assertion.
Last error thrown code, I leaving here as an example.
Then('click work order from the work order list {int}', (i) => {
cy.xpath(`//div[contains(#class, 'workorder')] //div[contains(text(), '` + getWorkOrderWithNoAttachment(i) + ` /` + `')]`)
.scrollIntoView()
.should('be.visible', { setTimeout: 10000 })
.click()
})

Related

How to get cypress to return children length of 0 when there isnt any children

So I am writing a test that will add a card to a container(payment-card-container) and I want to confirm an element was added later by seeing if the children have increased by 1. But I am having issues when we try to count the children length when there isnt any. I am currently using the below:
cy.get('[data-test-id="payment-card-container"]')
.children()
.its('length')
.then(length => {
const childrenLength = length;
})
But Cypress seems to get an error because it cant find the children (Error below).
Timed out retrying: Expected to find element: ``, but never found it.
Is there a way this can work when there isnt any children and it returns the value of 0?
The problem with using a jQuery expression like
Cypress.$('[data-test-id="payment-card-container"]').children().length
is you don't get the Cypress retry for async updates.
If adding a payment card calls an API, the above expression will falsely report 0 children instead of waiting for the DOM to update.
There's really no good way to handle the no-cards situation,
Except
set up your test scenario such that there are no cards initially
add a card
confirm that there is now exactly one card
If you must test for zero children, a trailing .should() will remove the error message.
cy.get('[data-test-id="payment-card-container"]')
.children()
.should('have.length', 0); // no error when should expression passes
// Add card here
cy.get('[data-test-id="payment-card-container"]')
.children()
.should('have.length', 1); // waits for async add-card operation
Tested with
<body>
<div data-test-id="payment-card-container"></div>
<script>
setTimeout(() => {
const div = document.querySelector('[data-test-id="payment-card-container"]');
const p = document.createElement('p')
div.appendChild(p)
}, 2000)
</script>
</body>
One hacky way that I could think of is this. You can use the jQuery length and children() property to check the length:
cy.get('body').then(() = > {
if (Cypress.$('[data-test-id="payment-card-container"]').children().length == 0) {
//Do Something
}
else {
//Do Something
}
})

Testcafe .parent() of Selector sporadically fails before timeout

I have a TestCafe test that checks if a Selector's parent exists and somehow it fails every other time. Here's the relevant code:
logWithTimestamp("Starts..."); // Prints "[2020-12-23T12:02:04.476Z] Starts..."
let state = await Selector('#indberetningsflow-knap-trin-stamdata', {timeout: 30000}).parent().exists;
logWithTimestamp(`State: ${state}`); // Prints "[2020-12-23T12:02:04.618Z] State: false"
await t.expect(state).ok() // Sometimes fails
As you can see, it fails after less than 200ms, even though the timeout is set explicitly to 30000. Now, I have an idea that maybe it fails when the selector is found, but the parent is not yet loaded. If this is true, why does TestCafe not wait for the parent to appear, and what can I do about it?
EDIT
I performed another experiment, and either there is something wrong with TestCafe or I have not understood something fundamental, but how can this fail after just 30ms?
logMedTidsstempel("Starts..."); // Prints "[2020-12-23T12:42:15.041Z] Starts..."
let state = await Selector('#indberetningsflow-knap-trin-stamdata', {timeout: 30000}).exists;
logMedTidsstempel("Found child."); // Prints "[2020-12-23T12:42:15.072Z] Found child."
await t.expect(state).ok(); // <- fails :(
To make your code example work, do the following:
Remove the await keyword from Selector
Remove the timeout option from Selector and pass it to the assertion method
...
let state = Selector('#indberetningsflow-knap-trin-stamdata').exists;
await t.expect(state).ok({timeout: 30000});
...
You may also wish to refer to the following help topic: https://devexpress.github.io/testcafe/documentation/guides/basic-guides/select-page-elements.html#selector-timeout

Testcafe Wait until an element has a specific text

After uploading an image with TestCafe the server will do some processing. While this time a label on the website will have "Inprogress" as a label. After the server is ready it will change to date. However, I want to tell the Testcafe script to wait until the label is not "Inporgress" anymore.
For this I did:
const DeliveryStatus = {
element: Selector('div.cl-asset-published').with({timeout: 70000}),
delivered: 'Inprogress'
};
And in the script I have
await t
.expect(DeliveryStatus.element).notContains(DeliveryStatus.delivered, { timeout: 70000 })
But this step fails. The message I got is "AssertionError: object tested must be an array, a map, an object, a set, a string, or a weakset, but function given" but I do not have any idea why.
Any suggestion to fix this issue?
You pass an element selector that returns the element but not a string to the expect function. Try using the element's innerText property instead as follows:
await t
.expect(DeliveryStatus.element.innerText)
.notContains(DeliveryStatus.delivered, { timeout: 70000 })

YouTube API: Uncaught SyntaxError: missing ) after argument list

I'm using the YouTube API and I keep getting
"Uncaught SyntaxError: missing ) after argument list" for the second line of code here:
$(".addVideoUrlBtn").on("click", function(){
player.loadVideoByUrl(mediaContentUrl: videoUrl,
startSeconds:0,
suggestedQuality:"large"):Void
})
The code is practically copied and pasted from YouTube api docs here: https://developers.google.com/youtube/iframe_api_reference so I'm not sure why I'm getting an error.
you're taking the docs too literally. The examples shown are a) not valid js (because they aren't supposed to be) b) showing the TYPES of expected argument
when they say
player.cueVideoById(videoId:String,
startSeconds:Number,
suggestedQuality:String):Void
they mean that the function player.cueVideoById takes arguments videoId, startSeconds, and suggestedQuality which are a String, Number, and String respectively and that its return type is Void (nothing)
$(".addVideoUrlBtn").on("click", function(){
player.loadVideoByUrl(url, 0, "large")
})
is that you want

PhantomJS Parse Error On Specific Sites

When I try to run the following extremely simple PhantomJS script, I get a parse error:
var page = require('webpage').create();
page.open('http://compare.nissanusa.com/nissan_compare/NNAComparator/TrimSelect.jsp', function (status) {});
Anyone know why this could be happening? The error message is not helpful at all... It just says "Parse Error".
Could this be a bug in PhantomJS?
I am using PhantomJS version 1.9. I'm able to run the above script with other URLs, but for some reason certain URLs return a parse error...
Any help would be greatly appreciated!
It's simply because there is a javascript error on the web site http://compare.nissanusa.com/nissan_compare/NNAComparator/TrimSelect.jsp. Parse Error is not because of your code.
Phantomjs does not really loves js error when loading a page, that's why it's important to add an error handler.
To easily catch an error occured in a web page, whether it is a syntax error or other thrown exception, use page.onError.
Here is a basic example :
page.onError = function(msg, trace) {
var msgStack = ['ERROR: ' + msg];
if (trace && trace.length) {
msgStack.push('TRACE:');
trace.forEach(function(t) {
msgStack.push(' -> ' + t.file + ': ' + t.line + (t.function ? ' (in function "' + t.function + '")' : ''));
});
}
console.error(msgStack.join('\n'));
};