What would be an easy way to check if a `q-input` element is in a error state? - cypress

I have q q-input with a data-cy="inputEmail" property
Is there an easy way to check if the q-input is in an error state ?
The data-cy prop is attached to the native input element and it looks like the only way is to use some relatively complex css selectors, for instance by checking if the input's parent's parent has a text-negative class ?

Ideally from an e2e perspective you want to test for what a user sees, for the presence/absence of the error message
cy.get('[data-cy="inputEmail"]')
.parent('.q-input')
.should('contain', 'must be a valid email')
If you look at the DOM, nothing changes on the input itself.

So assuming that in the error state text-negative class is added to the element, so you can assert the presence of this class like:
cy.get('q-input selector').should('have.class', 'text-negative')

Related

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.

how to call clear method on the element object

In my project I have located the text_Field via some other element(via label), something like
element.following_sibling(tag_name: 'input').send_keys 'something'
But now it's typing into the text_field without any problem but I am missing clear method of text_field as it combines both clear and type together. Now I have to call clear method on element.following_sibling(tag_name: 'input') but since it's returning element object, I couldn't do that. Is there any way I can call clear method here? Or can I pass this object by some way to the text_field() method? Any help appreciated.
I know it can be called by converting the watir element into selenium element as given below
element.following_sibling(tag_name: 'input').wd.clear
But here I am missing WATIR waiting time for an element.
This appears to be a limitation in Watir's adjacent methods:
klass = if !plural && opt[:tag_name]
Watir.element_class_for(opt[:tag_name])
elsif !plural
HTMLElement
elsif opt[:tag_name]
Object.const_get("#{Watir.element_class_for(opt[:tag_name])}Collection")
else
HTMLElementCollection
end
Notice that only the :tag_name is used for determining the element's class. For input elements, we need to also consider the type attribute so that we can the right sub-class.
We should fix this in Watir (logged as Issue 878), but in the mean time, you can manually correct the class (ie Watir::TextField) using #to_subtype:
element.following_sibling(tag_name: 'input').to_subtype.clear
I got an answer to my question now.
Here is the answer.
b.text_field(element: element.following_sibling(tag_name: 'input').wd).set 'something'
If anybody has any better idea, please write your answer.Thanks.

How do i clear a multi-select input using 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.

capybara acceptance test - how to select the right element from inspecting the UI

In this crud test I create a log entry with #notes and will try to update the log by replacing #notes with #updated_notes.
#notes = Faker::Crypto.md5
#updated_notes = Faker::Crypto.sha256
This block of code to create the log entry works. I used within and the id's of divs in the source code with inspect.
it 'User can update manpower log entry' do
# create a new entry
within '#manpower_log_div' do
find('#manpower_log_notes').send_keys(#notes)
click_button "+ Add"
expect(page.has_css?('td', #notes)).to be true
end
Here I try to click the already existing notes on the page, which lets me edit them.
# click the already existing notes to be able to edit them
within '#manpower_log_div' do
find('#inline_edit').click
end
The error received is
Capybara::ElementNotFound:
Unable to find css "#inline_edit"
Inspecting the element gives us this, but notice the id of the object is too specific: data-object_id="11747753". What element can I place in find that I can use every time I run this test?
<span textarea_cols="50" class="inline_textarea_edit inline_editable" data-object_field="notes" data-object_id="11747753" data-object_class="ManpowerLog" data-custom_callback="" id="ManpowerLog-11747753-notes" data-value_required="false">a5c3e556f108fd29b00150ca736c82d6</span>
You can find the element by any valid CSS selector that would match it. In your example you could use class or data attribute - or a combination of both.
find('span.inline_textarea_edit[data-object_field="notes"]').click()
In your code find('#inline_edit') is looking for an element with id inline_edit. As Thomas Walpole mentioned you can find your button using css selector for example by class:
find('.inline_textarea_edit')
or
find('.inline_editable')
or
find('.inline_textarea_edit.inline_editable')
Make sure that class is uniq for that element. If not, you'll need to use something else then class or something else together with class, you need to look for uniq attribute of that element.
Also make sure that your element is within element with ID manpower_log_div as you are using within '#manpower_log_div'
You can find more info about css selectors here: http://www.w3schools.com/cssref/css_selectors.asp

if page has selector - Capybara

I'm trying to implement a simple piece of logic that says if element exists on page do something`
The issue I am facing is that if the element doesn't exist then the find method provided returns an exception and will fail my test.
(Capybara::ElementNotFound)
so for example I want to do something like:
if page.find(".element")
do something
end
If the element doesn't exist then the test should just carry on as normal.
Is there a way to do this?
Consider using something like this:
if page.has_css?('selector')
do something
end
This method is described here

Resources