I am writing an automation test that checks user's ability to schedule an appointment via the calendar. Some dates on the calendar are disabled (aria-disabled="true" ), some are enabled and available for selection (aria-disabled="false"). Depending on when the test is running, the disabled/enabled status of each date is going to change. How do I use Cypress to select the first date button that is not disabled?
Here's what the button's HTML look like, just in case:
<button class="calendar-date" aria-label="Thursday July 28th, 2022" aria-pressed="false" aria-disabled="false" tabindex="-1" type="button" data-datestring="ThuJul282022">
28
</button>
You can filter the buttons
as a chained command
cy.get('button.calendar-date')
.filter('[aria-disabled="false"]') // buttons not disabled
.eq(0) // first one
.click()
as part of the selector
cy.get('button.calendar-date[aria-disabled="false"]') // buttons not disabled
.eq(0) // first one
.click()
An alternative to Fody's is to use .first(), which is just syntactic sugar for .eq(0).
cy.get('button.calendar-date[aria-disabled="false"]')
.first()
.click();
An alternative is to use :eq(0) pseudo selector.
There was a :first as well, but it's now deprecated.
cy.get('button.calendar-date[aria-disabled="false"]:eq(0)')
.click();
Related
I have a component with a Vuetify Select component:
<v-select
:items="corporations"
label="Corporation name"
data-test="corporation-name"
outlined
></v-select>
And I want to simulate a selection with a Cypress test:
cy.get('[data-test="corporation-name"]').select('Thorgate');
Unfortunately, I can't and I have this error message:
CypressError: cy.select() can only be called on a <select>. Your subject is a: <input data-test="corporation-name" id="input-13" readonly="readonly" type="text" aria-readonly="false" autocomplete="off">
I have also try to enter the value with a type()but Cypress told me
CypressError: Timed out retrying: cy.type() failed because this element is readonly:
Any idea, please?
The errors are pretty self-explanatory.
You're trying to apply a cy.select() method to an <input> tag, when you need a <select> tag
You're trying to .type() into a <input readonly>
cy.select() can only be applied to a <select> tag. If your v-select component renders a "custom select that is a bunch a dynamic divs and inputs INSTEAD of a select", then you need to create a custom Cypress command to handle a cy.customSelect() behavior. For example, it would: click on the main wrapper, find a option by typing words, and click on it... therefore selecting the option
For the second one, because your input is readonly, you can try to use {force: true} in your options when typing (cy.type("text", {force: true})
A little bit late, but, I hope this can help someone. ;)
The easier way I found to solve the problem with vuetify v-select, is using {force: true}, as stated by Jordan, and "pressing enter" at the end of string, like so:
cy.get('[data-test="corporation-name"]').type('Thorgate{enter}',{force:true});
https://docs.cypress.io/api/commands/type#Arguments
I use mailchimp to send subscribtion mails. In General forms I can customize the design of mails with Design it tab. But, is it possible to redesign Subscribe button text style, e.g to make Subscribe Button text in uppercase?
e.g #2 Change Subscribe to list to SUBSCRIBE TO LIST
Thanks.
I have found solution for you check screenshots
Step 1: http://awesomescreenshot.com/09161gcr88
Step 2: http://awesomescreenshot.com/06661gcvc5
Output: http://awesomescreenshot.com/0c061gcxfb
Thanks
There are at least two options that you have to change the text for the mailchimp subscribe button. In the embed code that Mailchimp provide there will be a section like this:
<input type="submit" value="Subscribe" name="subscribe" id="mc-embedded-subscribe" class="button">
This is the html for the button.
Option 1:
The css rule that will match this element is #mc_embed_signup .button. So you can add the following lines to your css file and your button should now be uppercase.
#mc_embed_signup .button {
text-transform: uppercase !important;
}
It is important to add !important because it is likely that the mailchimp css file will be loaded after your own css file. If this is not the case then you do not need to add !important.
Option 2:
In the html that they have given you, you can also change the attribute called value to other text, in your case SUBSCRIBE TO LIST.
<input type="submit" value="SUBSCRIBE TO LIST" name="subscribe" id="mc-embedded-subscribe" class="button">
Option 1 separates the two concerns of layout and content, so it might be preferable. However for a simple case like this option 2 would also be acceptable.
React-A11y yells at my Modal for 'tabIndex' and 'role'. My Modal looks like this:
<Modal
aria-label="..."
tabIndex={-1}
role="Dialog"
show={this.state.showInfo}
onHide={this.closeInfo.bind(this)} >
<Modal.Header tabIndex={9} role="Dialog" closeButton>
<Modal.Title tabIndex={-1} role="Dialog">...</Modal.Title>
</Modal.Header>
<Modal.Body tabIndex={-1} role="Dialog">
...
</Modal.Body>
</Modal>
As you can see from above, I do have tabIndex and role in every Element, but when I checkout React plugin I found out that A11y is yelling at the child of Modal that I can't access:
I am not allowed to use other modified Modals like React-Accessible-Modal. So is there any ways for me to go around to get rid of this warning? Thanks
Top element is correct. Immediate child div should have role="document" and NO tabIndex. In fact only your root element (the dialog box) should have tabIndex="-1". All other roles should be removed.
Tabindex affects tabbing order. If you set it 0, then that element will be able to receive focus via tabbing. I would avoid this if possible. Browsers allow focus on interactive elements. Consider wrapping elements you want to receive focus in an anchor or the like.
Tabindex as a positive is a no no. Totally messes up tabbing order.
Tabindex -1 is actually fine, but ONLY if that element is to receive focus programmatically via js
[Element].focus();
So your dialog should programmatically receive focus and just allow a natural tabbing order for the rest.
Note: trap focus in the modal until the user closes the modal. Then return focus to the modal trigger(anchor or button, I prefer anchor)
I want to trigger an event when an element is removed from the DOM.
In one of my templates I show a checkbox only when a condition is met:
{{#if some.thing}}
<input type="checkbox" class="checkbox">
{{/if}}
This checkbox later then is converted to a Bootstrap Toggle component.
What it does is, it hides the original checkbox and adds some markup to the document. All OK with that.
Now, if my collection changes and the condition, which previously was met, now evaluates to false, the checkbox is removed from the DOM. The node created from Bootstrap Toggle though stays present. So I want to remove the nde when the checkbox is removed.
I thought I could to this with the DOMNodeRemoved event but have some issues there:
Template.myTemplate.events({
"DOMNodeRemoved input.checkbox": function(el) {
$(el.currentTarget).bootstrapToggle('destroy');
}
});
The event fires, but somehow it ends in a cascade when I call bootstrapToggle('destroy') and the browser freezes. Also the event fires multiple times before and it makes me think this is not the correct way to watch for removed nodes in the first place.
Is there any better way to watch for removed elements and fire an event before they are deleted?
I know I could simply call a helper from my template, manually check if the node exists and delete the node with jQuery. But I'd like to see if this is possible with Meteor.events instead.
If you place the input (and the new bootstrap node/s) inside a child template, this should "just work" out of the box.
<template name="parent">
{{#if some.thing}}
{{> child}}
{{/if}}
</template>
<template name="child">
<input type="checkbox">
<!-- additional bootstrap nodes get instantiated in child -->
</template>
In the above, if some.thing === false the input and the new node/s will be removed from the DOM by Meteor automatically.
You'll have to forgive me for asking a somewhat trivial question here, but I'm generally curious if there's a better way of detecting if a button has been pressed. I'm guessing this would apply to anchor tags also.
Presently I have two submit buttons (so I cannot use $(form).submit in this case), both of which will change another field when they are activated:
<button id="accept" type="submit">Accept</button>
<button id="decline" type="submit">Decline</button>
To achieve this I have detected a click event, and the Enter keypress event separately:
$('#accept').click(function(){ $('#decision').val('Agree'); })
$("#accept").keyup(function(event){
if(event.keyCode == 13){
$('#decision').val('Agree');
}
});
I guess more than anything I'm wondering if there is a way to simplify this code, as it's rather cumbersome, especially if there's a lot of processing (you could create a function, but that's yet another step) and since jQuery seems to have most things covered, I'm surprised after trawling the internet I can't find a cleaner solution.
(with the above I was worried about other ways to mimic the button press, such as hitting space, although that seems to be covered!)
Thanks!
For a button element, both the spacebar and the enter key being presses on a button will generate a click event according W3C event specifications. You should not have to do any special processing to handle that.
As for using $(form).submit(), you can. Just change your buttons to not implicitly submit the form by chaning them to push buttons (W3C):
<button type="button" id="...">...</button>
Then in your handler you can do:
$('#accept,#decline').click(function(event){
$('#decision').val($(event.target).text());
$(form).submit();
}
If you need to you can do some processing on $(event.target).text() to make 'Decline' null/emptystring if necessary.
you can do something like this to make the click a little better: (using a function is necessary here to get something better):
function setDecision(value){
$('#decision').val(value);
}
$('button[type=submit]').click(function() {
var val = $(this).text();
setDecision(val);
});
$("button[type=submit]").keyup(function(event){
var val = $(this).text();
if(event.keyCode == 13){
setDecision(val);
}
});
I think I understand your question, and there may be some precedence to be found in this related topic.
jQuery: how to get which button was clicked upon form submission?
This method avoids adding the .click() event to each button, though that may be a viable option for your application.
Hope this helps!
Mason
Add name="decision" and value="Accept" / value="Decline" (accordingly) to the submit buttons
This way you do not need javascript to handle this at all...
And if the 'Accept' button is the first, then pressing enter inside any form field will also trigger that one
Sample:
<form action="1.html" method="get">
<input type="text" name="in">
<button type="submit" name="decision" value="Accept">Accept</button>
<button type="submit" name="decision" value="Decline">Decline</button>
</form>