Cypress, retrying against element thats no longer attached to the DOM - reactjs

I'm currently using cypress to test that a 'pill' element is added on the frontend when the data gets to a particular state.
I identify the row being targeted using cy.contains()
I then chain it with parents('tr').contains('<string>') to identify that the pill I want is being added
The only problem is because the cleanup logic that happens prior to the test triggers a third party webhook that my app responds to, sometimes the row I'm targeting gets removed (after its been found using the first cy.contains() command) and then re-added to the DOM before it reaches its final state.
I believe this is then what causes the second part to fail - cypress appears not to have realised its been detached from the DOM and times out expecting to find my <string> on the detached node.
The full chain looks something like this
cy.get('table')
.find('tr') // Get all the rows
.contains('stringToIdentifyMyTableRow') // Get the text in the specific row I care about
.parents('tr') // broaden scope to whole row
.contains('pillString') // Find text I'm looking for
It seems like its found everything after the .parents('tr') command so its not bothering to retry, even when they are actually detached from the DOM - rather its continuing to look for the pillString in the detached node. What I'd like it to happen is for cypress to continually retry the whole chain until the application reaches its intended state.

Try updating to the latest version 12. It has a new feature that retries when elements are detached from the DOM docs.cypress.io/guides/references/changelog#12-0-0

Maybe try eliminating the .parents('tr') step
cy.get('table')
.contains('tr', 'stringToIdentifyMyTableRow')
.contains('pillString') // should be pill cell
It's easy to get detached errors with React because of the frequent re-render of components.
Your test has no action to cause a re-render, if the webhook is doing it then you need a way to start the test after the webhook has run.

Related

How React Virtual Dom is faster? At the end of all its going to hit call browser API to update the real DOM

I read through all the articles in internet. Still i cant understand and mind is puzzling me questions again and again that is
At the end of all the virtual DOM it is going to call the browser API to update the real DOM then how come it will be faster?
Is virtual DOM of React have special access to browsers core API's to modify?
I cant understand? Any resolves this questions Thanks in advance
Here is a talk given circa 2013 (v0.4.0) by the two guys behind React. They describe exactly how it works. Unlike data binding and dirty checking (Angular, etc.) React uses one render method that's called recursively. It then generates a long string that is a representation of the DOM. The concept is actually really simple.
https://www.youtube.com/watch?v=XxVg_s8xAms
Yes, you are right finally the task is to update real dom but the virtual dom comes in picture before updating the real dom. how ?
Suppose you want to update any/many element(s) in Dom tree element then there should be a mechanism to find which element(s) needs to be updated in real dom i.e the browser screen we see.
So this dom finding algorithm executed in virtual dom i.e a javascript copy of real dom(a html dom tree).
React creates two virtual dom, one from existing real dom and other from the changes made. These two virtual dom comparison saves time. The difference of this comparison used for updating real dom.
At the end of all the virtual DOM it is going to call the browser API to update the real DOM then how come it will be faster?
Any speed benefits come from minimizing the number of DOM manipulations that are needed and doing them all at once. The virtual DOM is react's way of calculating the minimum set of changes.
Here's what i mean by calculating the minimum set of changes: The page starts off looking one way, and then you want to make it look some other way. To get there, you're going to need to make one or more changes to the DOM, but there are many different ways you could do it.
A really bad way to update the page would be to wipe the entire document, and then rebuild every single element from scratch. Most likely though, you can reuse most of the page and just make a few updates to select parts of the page: add a div here; update a property there, add an event listener there. That's what you want: a small number of steps that take the old page and turn it into the new page.

Why explicit wait is waiting for entire wait time even though element is visible/clickable before the wait time is over

I have given a wait time for 60 sec, and i am using wait until element to be clickable/visible but script is waiting for whole 30 secs even though the element is visible on UI and also clickable?
I tried using latest selenium version, tried using different waits also using different locators. but it did not work
The reasons could be in:
The element belongs to iframe so you need to switch to the iframe prior to attempting locating anything inside it
The element belongs to Shadow DOM so you need to locate ShadowRoot object, cast it to the WebElement and find the sub-element you want to click
Your locator is not correct, try getting the page source and saving it to a file. Once done use your favourite browser developer tools to locate the elemen
The syntax of your Explicit Wait is not correct. Check out Explicit Waits and How to use Selenium to test web applications using AJAX technology for code examples
Going forward consider adding page source and your code to your question as the chance you will get the comprehensive answer will be much higher, otherwise we have to go for "blind shots"

Can you handle state in this example without Redux or Flux, and if so how would you go about doing it?

Suppose I have a timer structured so that you can view and time multiple projects at once, and within each project you can view and time multiple tasks. Since this is a timer, you can only time one task at a time, and therefore one project at a time.
Because of these restrictions, I've separated the timer into three separate structures:
TimerContainer (outer, holds and displays all project objects)
ProjectContainer (middle level, holds only one project, with all tasks associated with the project)
TaskContainer (inner level, holds only one task).
Only the TimerContainer and ProjectContainer hold state.
TimerContainer:
The TimerContainer doesn't know anything about the tasks, but it does the initial API call to seed all projects and tasks with starting values.
The TimerContainer is also concerned with which project is currently tracking time (i.e. holds a projectID value for whichever project is currently timing).
ProjectContainer:
Each ProjectContainer holds information about which task is currently timing (if any), and updates (both here and via an API call) the time spent on each task after they've completed timing.
At that time it informs the TimerContainer it (that project) is no longer timing.
As props the TimerContainer is giving ProjectContainer the currently tracking project ID, list of tasks and their seed values, and various project information.
Here is my question:
If I update the TimerContainer's "Currently Tracking ProjectID" value, it will trigger a re-rendering of all the ProjectContainers, including the one that just updated one of its tasks' times. That, in my mind, seems to revert it back to the original seed value of that task unless I update the (now static) seed information held in the TimerContainer for that specific task.
If I do that, it makes me think that I have to set the state for both the seed information and the currently tracking projectID with the same call, because if I do it sequentially I'm not sure if it will get to the second state change request.
If this is indeed a problem (and please feel free to say otherwise), I imagine it could be alleviated by Redux or Flux, but given an already established architecture I would like to see if there are clean ways of handling this without bringing in another library first.
Bottom line, how is this solved cleanly without another library?
Update:
It seems as if I was confused about the way re-rendering affected state initialization (namely, it doesn't). I modified Adam's example below to prove that to myself
(link here )
After that realization, the solution to my problem simply becomes writing up a function that would handle "Currently Tracking ProjectID" prop value change on each of the ProjectContainers.
Another thing to implement is the shouldComponentUpdate function (thanks again) by checking if the ProjectID was related to that ProjectContainer.
A component re-rendering shouldn't cause that component to lose it's internal state. Here's an example: the child component re-renders because the parent changes state and passes the child new props, but the child keeps its own internal state.
As far as design options in general, there are a bunch. Here are a few I'd consider:
Re-rendering is a performance hit, so consider customizing the shouldComponentUpdate function for child components to keep them from rerendering
Try to make as many child components stateless or pure as possible
Consider not persisting the "seed" values in the parent component - not sure if there's value to knowing the initial value, but if you just pass that down to the child components, they can store and increment that
On the whole though, it sounds like you might benefit from a store. Being able to separate out organization of state from functionality can be helpful.

Extend Store class to always execute a function after load on ExtJS

I am working on a project where we were asked to "patch" (they don't want a lot of time spent on development as they soon will replace the system) a system implemented under ExtJS 4.1.0.
That system is used under a very slow and non-stable network connection. So sometimes the stores don't get the expected data.
First two things that come to my mind as patches are:
1. Every time a store is loaded for the first time, wait 5 seconds and try again. Most times, a page refresh fix the problem of stores not loading.
Somehow, check detect that no data was received after loading a store and, try to get it again.
This patches should be executed only once to avoid infinite loops or unnecessary recursivity, given that it's ok that some times, it's ok that stores don't get any data back.
I don't like this kind of solutions but it was requested by the client.
This link should help with your question.
One of the posters suggests adding the below in an overrides.js file which is loaded in between the ExtJs source code and your applications code.
Ext.util.Observable.observe(Ext.data.Connection);
Ext.data.Connection.on('requestexception', function(dataconn, response, options){
if (response.responseText != null) {
window.document.body.innerHTML = response.responseText;
}
});
Using this example, on any error instead of echoing the error in the example you could log the error details for debugging later and try to load again. I would suggest adding some additional logic into this so that it will only retry a certain number of times otherwise it could run indefinitely while the browser window is open and more than likely crash the browser and put additional load on your server.
Obviously the root cause of the issue is not the code itself, rather your slow connection. I'd try to address this issue rather than any other.

How to wait for DOM to load in protractor tests

I am hitting the url in browser by "browser.get(url)" and then I am expecting something to be present on the screen. But My test cases are failing because it is taking some time to load the page and test cases are executed before the page loads. So is there a way where I can wait for DOM to load and then the rest of the test cases are executed. I do not want to put sleep as the time to load the page is not consistent and it is unnecessary delay in executing the tests.
I am looking for some solution where we can wait for DOM to load and then we go to next tests to execute.
I solved this by waiting for some specific element to be present on the screen and then perform next activity: here is the code, how I am waiting for the element:
browser.wait(function(){
return browser.driver.isElementPresent(by.id(elementId));
},30000);
So, if you have doubt that execution can happen before the element is present on the screen, then just wait for some element to be present on the screen and then perform next activity.
Hope this will help other, who will face same kind of issues.
You can put a timeout for the script in your config
jasmineNodeOpts: {defaultTimeoutInterval: 70000}
This will wait AT MAX for specified time.

Resources