How do i clear a multi-select input using Cypress? - cypress

How do i clear (deselect) all options within a multi-select input using Cypress?
The documentation here does not seem to cover this scenario: https://docs.cypress.io/api/commands/select.html#Syntax
The clear() command apparently cannot be applied to selects, as you might expect
https://docs.cypress.io/api/commands/clear.html#Syntax
I have tried passing an empty string / array / null to select() but i get the following error:
CypressError: Timed out retrying: cy.select() failed because it could not find a single <option> with value or text matching: ''

Since Cypress 8.6.0, this is supported in Cypress: https://stackoverflow.com/a/69537449/3474615
Before 8.6.0:
You can use cy.invoke() to call the .val('') method on the underlying JQuery element, which will cause it to be cleared.
Like this:
cy.get('select')
.invoke('val', '')
Note that this will not emit the change event. If you want to test that your code reacts to the change event, you can cause it to be emitted with cy.trigger():
cy.get('select')
.invoke('val', '')
.trigger('change')
I've also filed a feature request for this functionality, as it does seem like something that should be included with Cypress by default.

cy.select([])
cy.select([]) called with an empty array, can now be used to clear selections on all options.
Note: update cypress to v8.6.0 or higher to work.

Related

Wait until element has disappeared in Cypress

please, tell me what methods to use to wait for a loading screen element to disappear? PS. I'm not using an API request.
I tried to use two methods, but it doesn't work properly:
1. cy.get('#loading', { timeout: 30000 }).should('not.be.visible');
I get the error: -- Timed out retrying after 30000ms: Expected to find element: #loading, but never found it.
2. Used plugin (cypress-wait-until) like so cy.waitUntil(() => {document.querySelector('#loading') === null};
This approach doesn't find the element at all.
If you are trying to retrieve an element that is not in the DOM, use not.exist instead:
cy.get('#loading').should('not.exist');
In cases where you do need to wait, you can try using cy.wait:
An example use case for this might be if Cypress has to route to your page first and you want to ensure the page loads before you start testing:
cy.wait(200);

How to validate Browser Error's message with cypress

For example if user dont fill this field and press "continue" button, this error message will pop up.
I wonder is there a way with Cypress that I check that error message was displayed?
Kind regards
You can make this assert : cy.get('input:invalid').should('have.length', 1)
See https://github.com/cypress-io/cypress-documentation/pull/1919/files how to assert the validation message
I know this is an older question but here is another solution.
cy.get(`[data-testid="XXXX"]`)
.invoke('prop', 'validationMessage')
.should((text: string) => {
expect(text).to.contain(YYYY);
});
Using the above code here is what happens:
You grab the input / textarea element using cy.get Note: it is recommended to use a data-testid or obtain the element by something less brittle so the test doesn't fail if the text changes etc.
Using the invoke method, you can check validationMessage against prop then then, obtain the inner text and use expect to check if it's valid. This is very handy if you use custom validation messages.

Cypress - How to Wait for an attribute value to be false in Cypress

I have a website which has everything in an iFrame. My scripts are failing because cypress is not able to wait for loading bar as cypress does not support iframes as of now. I want to write a custom command which wait until attributes 'ng-reflect-loading' value is changed to false.
I have tried with below code but its not working and halts cypress runner. Reference Thread 136
cy.get('iframe').iframeLoaded().its('document').getInDocument('.main >ng-component > :nth-child(1)').then(function($loading) {
while( $loading.attr('ng-reflect-loading')!='false')
{
cy.log('waiting')
}
})
Can anyone please help on this.
I don't have any insight of how iFrames work. But is 'ng-reflect-loading' eventually hidden?
In that case this check should work:
cy.get('.ng-reflect-loading')
.should('not.exist')
If it remains existing but the value should change you could either check on the first value not existing:
cy.get('.ng-reflect-loading')
.should('not.contain.attr', 'attr_name', 'first value')
Or if the value changes, you could check for the second value to be available:
cy.get('.ng-reflect-loading')
.should('contain.attr', 'attr_name', 'second value')

Wait on a text to be appear in SitePrism Capybara Framework

I tried to wait on a text before perform any action by follows SitePrism URL https://github.com/natritmeyer/site_prism in this section>> "Methods Supporting Capybara Options".
#page.wait_until_<Element>_visible :text => "Some Text!!!"
But i am getting below error:
undefined method `zero?' for {:text=>"Some Text!!!"}:Hash (NoMethodError)
Why i am getting this error? Am i doing something wrong?
Looking at the site_prism code - https://github.com/natritmeyer/site_prism/blob/master/lib/site_prism/element_container.rb#L134 the generated method takes a timeout, and the options. It seems like you need to pass the timeout value if you want to pass other options
wait_until_<Element>_visible <timeout value in seconds>, text: "Some Text!!!"
Seems like an error in the documentation, or some old defaulting behavior was removed or something
Old question
For those still hitting this SO answer, this has been remedied in v3 of the API and is no longer an issue. See: https://github.com/natritmeyer/site_prism/blob/master/UPGRADING.md#wait_until-methods
wait_for_ methods now no longer exist, and you should just implicitly wait by calling element i.e. my_button
If you want it to wait, you can modify the Capybara.default_wait_time or pass in a wait key i.e. my_button(wait: 3)

How to use querycommands in CKEditor

In TinyMCE i am able to get the currently selected values by using queryCommandValue and queryCommandState like this:
tinymce.activeEditor.queryCommandValue("FontName");
This would get me the selected fontname. How would i do something like this in CKEditor?
The command state can be checked using the following available methods in CKEDITOR.command list.
previousState
Indicates the previous command state.
alert( command.previousState );
state
Indicates the editor state. Possible values are:
CKEDITOR.TRISTATE_DISABLED: the command is disabled. It's execution will have no effect. Same as disable.
CKEDITOR.TRISTATE_ON: the command is enabled and currently active in the editor (for context sensitive commands, for example).
CKEDITOR.TRISTATE_OFF: the command is enabled and currently inactive in the editor (for context sensitive commands, for example).
Do not set this property directly, this can also be achieved using the #setState method instead.
e.g
command.setState( CKEDITOR.TRISTATE_ON );
one can also check the state to do execute a command or to do some task
if ( command.state == CKEDITOR.TRISTATE_DISABLED )
alert( 'This command is disabled' );
queryCommandValue can be done while executing a normal command like command.exec(data) and this value of data should come from some variable in which this value is stored.
You can get the document to perform direct DOM calls as you want by doing it this way
CKEDITOR.instances.editor1.document.$.queryCommandValue("FontName")
but I must warn you that directly calling the DOM instead of using the CKEditor API is gonna be harder. CKEditor has been designed to wrap the differences between browsers, and if you want to skip that and use other API then you'll have to redo a lot of work.

Resources