Check for mui selected table row in cypress after animation - material-ui

I'm building an application which has a list represented as mui table.
There is always one entry selected in this list.
After I create an new list entry an useEffect hook will ensure that the new entry will be selected.
Now I'm writting an cypress test, which should only continue his work after the selected list entry was updated (after the list entry creation).
For this I wrote following code.
Initially the list value is "Cooler Kunde". But after the list entry creation it is "Neue Position".
cy.get('.Mui-selected.MuiTableRow-root') // I found a <tr> tag with this two classes to identify my html tag
.children()
.find('p')
.should('have.text', 'Cooler Kunde'); // this works
// doing some stuff which causes the new selected line
cy.get('.Mui-selected.MuiTableRow-root')
.children()
.find('p')
.should('have.text', 'Neue Position'); // this fails
But I receive the following error:
Timed out retrying after 4000ms: expected '<p.MuiTypography-root.MuiTypography-body2.css-1xsg5cg-MuiTypography-root>' to have text 'Neue Position', but the text was 'Cooler Kunde'
But I can fix this issue by a wait. But I don't like to use a wait, which always delays my tests:
cy.get('.Mui-selected.MuiTableRow-root')
.children()
.find('p')
.should('have.text', 'Cooler Kunde');
cy.wait(1000);
cy.get('.Mui-selected.MuiTableRow-root')
.children()
.find('p')
.should('have.text', 'Neue Position');
Do you have an idea how I can fix this issue without using the cy.wait(1000)?

Reduce it to wait(0) which will not delay the test but will allow app actions to complete.
It makes Cypress give up the thread and allows the app code to run.

Related

Keep two react-bootstrap-typeahead inputs in sync

So I have an application with a dashboard and a main page that has a header. Both of them have a react-bootstrap-typeahead input to perform the same action - a search to open something on a map.
What I would like to achieve is:
when the user search something on the dashboard, the main page opens with the search result and on the header, the search input there shows what was searched on the other component.
on the other hand, when the user search something on the search input on the main page header, and then goes back to the dashboard, the dashboard search input should be prefilled with the value previously searched on the main page.
What I have tried so far:
So when the user picks a search item result, that string is saved on the application state using redux. I also clear it manually when the user clicks on the clear search button. The RBT component is defined to use this variable, as in:
<AsyncTypeahead defaultInputValue={props.currentSearchValue} ... />
This seams to work on the first time, i.e. when the user has not interacted with the other input yet. For example, with the application on a fresh state (just loaded) if on the dashboard I pick a search item, when going to the main page because that search input has not been touched yet. Then, when I pick a search item on the main page and go back to the dashboard, I wouldn't see it because setting defaultInputValue is not enough, as that input is not in its default state anymore.
Any tips? I have been running in circles so far. Tried the key/setKey workaround as described in another answer, but that wasn't enough to cover the case described on the previous paragraph. I also tried comparing the input value to the recorded value, but naturally when starting to typing with the input field the values would be different and therefore I cannot trigger a component reload based on that.
Thanks in advance.
Unless I'm missing something about your use case, the selected prop should do what you need. You can save the selected item(s) in your redux store and populate the typeahead with the value on the given page.
// Get the initial value from the store. This should be an array.
const typeaheadSelections = useSelector(...);
<Typeahead
...
onChange={(selected) => {
// Update the value in the store when the selection changes.
dispatch({
type: 'set-typeahead',
value: selected,
});
}}
selected={typeaheadSelections}
/>

How can i click on an item that is freshly created with an automated test?

How can I click on an item that is freshly created with an automated test using katalon?
In my katalon script I am adding one record and immediately I want to edit that record. So I want to identify the new one among old records.
WebUI.click(findTestObject('Object Repository/Page_MEDICALHUB Sales/button_SAVE')) //here I am saving
WebUI.check(???????) //here I want to select checkbox to edit
WebUI.click(findTestObject('Object Repository/Page_MEDICALHUB Sales/i_Sales_fa fa-pencil'))
checkbox is not checked
before try to check
Use this:
WebUI.waitForElementPresent(findTestObject('checkobx'), waitTime)
Since you have to wait for the element to be rendered, you will need to wait not only for it to be present (present in DOM) but also clickable:
WebUI.waitForElementClickable(findTestObject('Object Repository/checkbox element'), 30)
More info on Katalon Docs page.

Angular ngClass trigger change detection error when binded to ngModel validation

I'm trying to set the color of a label in Angular 2 depending on its email-validation like this:
<input type="email" name="email" [(ngModel)]="email" email #currentEmail="ngModel" [ngClass]="currentEmail.invalid ? 'error' : 'none'">
It works as expected on my page, however in Visual Studio Code I get the following error message:
Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'error'. Current value: 'none'.
So my questions are:
Why does this message show up?
Whats the right approach to do this task?
Why does this message show up?
You can find a good explaination of why in this issue
This is not a bug, it's a feature of dev mode working as intended. Calling enableProdMode( ) - when bootstrapping the app prevents the exception from being thrown.
That said, it's being thrown for good reason: In short, after every round of change detection, dev mode immediately performs a second round to verify that no bindings have changed since the end of the first, as this would indicate that changes are being caused by change detection itself.
In your plunk, you have the binding [attr.spinner]=isLoading, and isLoading changes as a result of your call to this.load(), which occurs when ngAfterViewInit is fired, which happens as a part of the initial change detection turn. That in itself isn't problematic though - the problem is that this.load() changes a binding but does not trigger a new round of change detection, which means that this binding will not be updated until some future round of change detection.
Whats the right approach to do this task?
Simply replace [ngClass] with [class]. I don't know why, but when trying to reproduce your issue in a plunker, I found out that [class] does not trigger the error.
Edit : use ng-invalid class
You can also style your element based on the angular class ng-invalid.
See this plunker

In Selenium IDE create node text title not found and give the error

Generate error Image screenshot :
I am also use command and run that i.e. type, typeAndWait, typeKeys, typeKeysAndWait , also give the error
Selenium IDE:
Command : Target
type : id=ctl00_Dialogproxy_deletenews_btnDelete
Reference box give the message text :
type(locator, value)
Arguments:
locator - an element locator
value - the value to type
Sets the value of an input field, as though you typed it in.
Can also be used to set the value of combo boxes, check boxes, etc. In these cases, value should be the value of the option selected, not the visible text.
I am send the image URL for all details
Edit: Image was hidden so make it visible.
This looks like it is again a duplicate of the issue you've noted in In Selenium IDE btnDelete (Button) not found
You follow up a "click" that loads a dynamic pop up with an action on a new element. It's possible that selenium is moving to fast for the pop up and the new elements are not in the DOM yet for selenium to access.
I suggest using a "waitFor" action, such as waitForElementPresent. You can also see if this is a case by inserting a pause (with 5 or 10 seconds). I do not recommend pause since it's a hard stop where as a waitFor command will take the minimum amount of time it needs.

MVC Html.textbox/dropdown/whatever won't refresh on postback

OK, let's start with the Html.Textbox. It is supposed to contain text read from a file. The file read is based on what the user picks from a dropdown list.
The first time it is fine. The user picks a value from the dropdown list. The controller uses that value to read some text from a file, and returns that text to the view via the view model. Everything is fine.
THen the user picks another value from the dropdown list. The controller reads a new value from a file and returns it via the view model. Debugging to the LINE BEFORE THE HTML.TEXTBOX is set in the view shows that the model contains the correct value. However, the textbox itself still shows the PREVIOUS value when the page displays!
If I switch from Html.Textbox to a plain input, type="text" html control, everything works fine. That's not so hard, but the same thing happens with my dropdown list -- I can't set the selected value in code. It always reverts to whatever was chosen last. Rendering a "select" tag with a dynamically-generated option list is a pain. I would love to be able to use Html.Dropdown.
What am I missing here?? This is such a simple thing in webforms!
When you post a form, the values that are posted are put into ModelState. When the HtmlHelper renders an html iunput element, e.g. Html.TextBoxFor(x => x.FirstName), it'll search various locations to get the value for the textbox... ModelState is before ViewData.Model in the list of locations. So there for, the previously posted value will appear in your textbox.
To fix this you could clear the ModelState value or update the ModelState value. BUT I would kinda view that as a hacky way of getting around the problem.
The real issue has more to do with the flow of the posts and requests. I would personally look into that and maybe implement the PRG (Post Redirect Get) pattern.
HTHs,
Charles
Following on from what Charles/Charlino said:
Model binding updates the ModelState object, which contains validation and model binding errors that are collected during model binding.
Inside an action method, model binding has occurred already to update the model, and generated the ModelState object. If you now update the value on the model inside the action, you must also manually update the model state (since the helpers use it to generate their HTML). Below is an example:
model.CaptchaIsValid = CaptchaService.ValidateAndExpireCaptcha(model.CaptchaAttempt);
if (!model.CaptchaIsValid)
{
ModelState.AddModelError("CaptchaAttempt", "Incorrect - please try again");
}
// I'll clear the value on each attempt, to force them to re-enter a CAPTCHA.
model.CaptchaAttempt = string.Empty;
// Since I updated the model, I must create a new ValueProvider result...
ValueProviderResult clearedValue = new ValueProviderResult(
model.CaptchaAttempt,
model.CaptchaAttempt,
CultureInfo.CurrentCulture);
// ... and update the ModelState's value.
ModelState.SetModelValue("CaptchaAttempt", clearedValue);
The biggest issue I see here is that you are trying to do a postback within MVC. That model is really not supported, and is actually way more trouble than it is worth (as it seems you are finding out). I would recommend using Ajax to update the contents of the dropdown dynamically.