Cannot select option from dropdown after the first time I run the test - jasmine

I'm writing protractor tests and I have a really weird issue. I need to click on a dropdown and select an item from it. I have a few other tests to select items from dropdown and they all work fine. But on this page, it works during the first run and from the second time, it clicks open the drop down but doesn't select the item.
It times out but doesn't show any error like not finding the element.
- Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
at ontimeout (timers.js:475:11)
at tryOnTimeout (timers.js:310:5)
(node:24118) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): CancellationError: ControlFlow was reset
Has anyone experienced anything like this? What can I try to make this work?

Related

How to trigger the event in AnyLogic and then make it cyclic?

I would like to make the cyclic event. This event periodically calculates some parameters of the model. However, the event should be triggered once by a condition. I have no idea how to do that.
I tried to make the event.reset() at the beginning and then restart it after the appropriate condition is met.
However, I received the errors:" agent cannot be resolved to a variable"
If I delete the reset and restart functions for the event, everything will be ok. The event is cyclic and works fine.
The double click on the error shows the stings where the error is occurred (highlighted with red color):
On model start-up, suspend the event by using:
event.reset();
Once the condition you have is met, use:
event.restart();

cy.type stop mid-typing, finishes after .wait

I'm seeing an issue where cypress (v6.9.1) is randomly stopping mid-type, despite the fact that no other events are triggering on our page, and continuing after a .wait as it proceeds to execute other commands.
cy.get(`[placeholder="Search"]`)
.clear()
.click()
.type(search) //types a portion of 'search', then stops
.wait(500);
//continues typing the rest of search
This issue is sporadic and can not be reliable reproduced, and can and has happened on any text input on our app. Any ideas on what could be causing it?
You can add a delay while typing something like below. Now each keypress will be delayed 50ms.
cy.get('[placeholder="Search"]').clear().click().type(search, {delay: 50})
When using a component like React Async Select and wanna select an option you can do.
cy.get("#elementid").type("Jef{enter}", { delay: 100 });
so each consecutive keystroke, it will wait 100 ms. Not the greatest solution as it's arbitrary.
I haven't found a better solution using cy.intercept so if anyone has one, please let me know.

Cypress not retrying assertion

My Cypress test is acting inconsistently due to an assertion set on header text. Here is my code:
cy.get('.heading-large').should('contain', 'dashboard') // passes
cy.contains('View details').first().click()
cy.get('.heading-large').should('contain', 'Registration details') // sometimes fails
If it fails, it is because the heading still contains 'dashboard' - Cypress appears not to have retried but gives error Timed out retrying: expected '<h1.heading-large>' to contain 'Registration details'
From reading about Cypress retry-ability, my understanding is that the should assertion should keep trying until timeout, which is set as "defaultCommandTimeout" : 5000. This feels true even if I have an element with the same identifier across two pages. There are no major performance issues with the app I'm testing.
The test seems more likely to fail if I am not watching the window and this issue looks like a possible cause.
Can anyone help determine: is there an issue with my test or Cypress, and how might I improve the test? I'm using Cypress 5.1.0 and Chrome 85 on MacOS Catalina.
It is failing occasionally because the request that fills the header with information has not resolved by the time the timeout has been reached.
You can solve this by setting up a route with a route alias to wait for that exact response from the request to resolve before you proceed with the click.
In other words, When you click(), there is a request sent that grabs the information you want to check for in the next get(). This response for this request has sometimes not resolved by the time your get() reaches timeout. You could increase the timeout but that's not recommended and not good practice here. Instead, wait for that specific response with route & route alias. If you do that, in every case, the last get() won't get called until the information it is looking for has been resolved.
I don't know your request but it would work something like this:
// setup the route and alias
cy.server()
cy.route("/youRequestUrlHere").as("myLovelyAlias")
// first get
cy.get('.heading-large').should('contain', 'dashboard')
// this click fires the request url from route() above
cy.contains('View details').first().click()
// wait for route to resolve using route alias
cy.wait("#myLovelyAlias").then((response) => {
// next get called after response resolves
cy.get('.heading-large').should('contain', 'Registration details')
}
Reference:
Route & alias
Route
Best Practice - get()
Network Request - wait()
edit:
As mentioned above, you could also cheat and set the defaultCommandTimeout to a higher number but that is not recommended because you could still run into cases where the response resolution takes longer than the timeout you've set. The route/wait pattern is the better, more stable approach.
Just in case you want to know how its done though, you would change your get() to something like:
cy.get('.heading-large', {defaultCommandTimeout: 60000}).should('contain', 'Registration details')
Again, other way would be much better.
Reference:
Cypress configuration
It looks like we need to wait for the Cypress bug "Some tests flake only if test runner's browser loses focus (or run headlessly)" to be fixed. This is because I have tried the alternative, helpful answers but am consistently facing the original issue when the window is out of focus.
Thank you to those who have answered and commented.

Cypress async form validation - how to capture (possibly) quick state changes

I have some async form validation code that I'd like to put under test using Cypress. The code is pretty simple -
on user input, enter async validation UI state (or stay in that state if there are previous validation requests that haven't been responded to)
send a request to the server
receive a response
if there are no pending requests, leave async validation UI state
Step 1 is the part I want to test. Right now, this means checking if some element has been assigned some class -- but the state changes can happen very fast, and most of the time (not always!) Cypress times out waiting for something that has ALREADY happened (in other words, step 4 has already occurred by the time we get around to seeing if step 1 happened).
So the failing test looks like:
cy.get("#some-input").type("...");
cy.get("#some-target-element").should("have.class", "class-to-check-for");
Usually, by the time Cypress gets to the second line, step 4 has already ran and the test fails. Is there a common pattern I should know about to solve this? I would naturally prefer not to have change the code under test.
Edit 1:
I'm not certain that I've 100% solved the "race" condition here, but if I use the underlying native elements (discarding the jQuery abstraction), I haven't had a failure yet.
So, changing:
cy.get("#some-input").type("...")
to:
cy.get("#some-input").then(jQueryObj => {
let nativeElement = jQueryObj[0];
nativeElement.value = "...";
nativeElement.dispatchEvent(new Event("input")); // make sure the app knows this element changed
});
And then running Cypress' checks for what classes have / haven't been added has been effective.
You can stub the server request that happens during form validation - and slow it down, see delay parameter https://docs.cypress.io/api/commands/route.html#Use-delays-for-responses
While the request is delayed, your app's validation UI is showing, you can validate it and then once the request finishes, check if the UI goes away.

Protractor - changing pages/views

I have a test case in Protractor which loads the home page and then clicks a button that redirects to another page. In that other page I want to grab the value of an element.
describe('todo list', function() {
it('should find the contact phone number from the home page', function() {
browser.get('http://homepage...');
element(by.id('re_direct_to_contact_page')).click();
var number = element(by.id('phonenumber')).getText();
expect(number).toEqual('412-....-...');
});
});
However although it loads the page it does not check the element value and the test case fails.
How can Protractor load another page to check a value?
NOTE: - I made up this example but in my real test case I am sending data from one page to another so I cannot load the page I want directly.
EDIT: STACK TRACE
protractor conf.js Using the selenium server
at http://localhost:4444/wd/hub [launcher] Running 1 instances of
WebDriver
Error: Error while waiting for Protractor to sync with the page:
"[ng:test] http://errors.angularjs.or/1.4.0/ng/test"
StackTrace: undefined
1 test, 1 assertion, 1 failure
It's possible that you might be facing a timing issue. Try re-structuring your test from this:
var number = element(by.id('phonenumber')).getText();
expect(number).toEqual('412-....-...');
To this:
expect(element(by.id('phonenumber')).getText()).toEqual('412-....-...');
While Jasmine and Protractor try to resolve every promise before moving on, sometimes it doesn't happen as quickly as you would like. Putting the entire promise chain into the expect helps to enforce the resolution of all of them before going through the matcher.

Resources