Second drop down list does not get filled with Cypress - cypress

I ran into a problem. Can anyone help me ?
So, I have two drop down lists and the second is dependent on the option I choose on the first.
Say, for example: The first drop down list has the options 'numbers' and 'letters', while the second drop down list is empty by default. However, when I choose the option 'letters' on the first drop down list, the second is filled with the options 'A', 'B' and 'C'. Manually, it is working fine, but when I select the first drop down list with Cypress, the second doesnt get filled. It remains empty, so I cant choose anything on it.
HTML:
<select id="list" class="selectpicker form-control" onchange=""><option value="0">select your preferences</option><option value="2">numbers</option><option value="3">letters</option></select>
CYPRESS:
cy.get('#list').select('letters')
it does select the option letters, I can see the option letters selected on the first drop down list, but nothing happens on the second.

The solution from what it seems is to force the click because, from what I could gather, cypress chooses the option but IT DOESNT CLICK THE OPTION! Is this a bug?
So, this is the giant that was necessery, in the end to make it work:
//choose the option on the first drop down
cy.get('#list').select('letters')
cy.get('#list').contains('letters').then(option => {
cy.wrap(option).contains('letters');
option[0].click();
cy.get('#list').contains('letters');
});
//choose the option on the second drop down
cy.get('#list2').select('A')
cy.get('#list2').contains('A').then(option => {
cy.wrap(option).contains('A');
option[0].click();
cy.get('#list2').contains('A');
});
//click on the button to save the options selected
cy.get('.saveButton').click()
when, normally, it should be only:
cy.get('#list').select('letters')
cy.get('#list2').select('A')
cy.get('.saveButton').click()
Do you guys think this is a bug ?

I think you should "force" the refreshing data from the "non-updated" dropdown.
Try to "click()" it.
Something like this:
cy.get('#list')
.contains('letters')
.then(option => { // Confirm have correct option
cy.wrap(option).contains('letters');
option[0].click(); // After click, mdc-select should hold the text of the
// selected option: cy.get('#list').contains('letters');
});
Maybe this link can help you: select dropdownlist item using cypress

alternatively you can select by value cypress docs
cy.get('#list').select('3')

Related

Click an exact match in cypress from drop down

Firstly ,I was doing cy.contains(option) with it was clicking the exact value eg -I want to click One but One One is also there so cy.contains not working.
I tried Regex but it is not working
I am trying to click the exact match from drop down writing test step as ;
cy.contains(new RegExp(option, "g"))
but not giving me correct output. I am getting error : Timed out retrying after 4000ms: Expected to find content: 'option' but never did.
Since you are using a dropdown, you can and should use the .select() command which will choose the option by exact match:
cy.get('select')
.select('One')
.should('have.value', 'One')
When the dropdown is like this, the above will choose the 2nd option.
<select>
<option>One One</option>
<option>One</option>
</select>
for the regex to work, you need to use the ^ and $ characters to indicate beginning and end of string
// works on <span>One</span> but not on <span> One </span> or <span>One One</span>
cy.get(`span`).contains(/^One$/)
// so you might want to also include white space
cy.get(`span`).contains(/^\s?One\s?$/)
You can click using the dropdown option if you now by default what is the option
cy.get(DROPDOWN IDENTIFIER).eq(NUMBER OF THE DROPDOWN MATCH).click();
What do you want is the .click() function to click on the match.
This will not work if you dropdown menu is a .

Inconsistent element query with Cypress

I'm trying to use Cypress to click a react-select element. However, I get very inconsistent results.
My code for clicking the element is as follows:
cy.get('div[class*=container]').contains('Brand').click()
Sometimes this works, sometimes it doesn't. Sometimes if I repeat this line twice (which is kind of hacky...), it works, but on other occasions it doesn't...
What would be the correct and fool-proof way to wait for this element to properly load and click it only then in Cypress?
I looked into this cypress repo and it suggested two way to do the click().
cy.contains('.product', 'First item')
.find('button.order')
.click()
.wait(1000)
cy.contains('.product', 'First item')
.find('button.order')
.click()
.click()
Because its a select element, what you would want to do is:
cy.get('div[class*=container]').select('Brand')
or
cy.get('div[class*=container]').contains('Brand').realClick()
Looking at examples of react-select, there are a lot of classes with container in them, so 'div[class*=container]' is not the best selector.
I understand class*=container is to circumvent the style hash which can change on compile.
Ideally, add a specific class to the source, as per the first example on the home page
<Select
className="basic-single"
...
then you have a link to the top-most element, which is clickable.
cy.visit('https://react-select.com/home')
cy.get('div.basic-single')
.should('contain', 'Ocean')
.click()
cy.contains('Green').click() // option selection
cy.get('div.select__control').eq(0)
.should('contain', 'Green')

Set option selection on mat-select to return placeholder after selection

I have the following Angular 6 code:
https://stackblitz.com/edit/angular-pl9wkw
I'm tryin g to make the select dropdown reset to the place holder once a selection has been made. I am using these two lines to try and reference the process:
#ViewChild('selectDropdown') selectDropdown: MatSelect;
and
this.selectDropdown.AppComponent.reset();
Alas, it does not work to set the dropdown back to the placeholder. I know that it can be set back to the placeholder, because I have the blank <mat-option></mat-option> selectable, and once you do select it, it sets it back to the placeholder.
Any thoughts ... anyone.
In your onChange method make the following change.
this.selectDropdown.value = [];
// this.selectDropdown.AppComponent.reset();
In your Onchange make following change
this.selectDropdown.value.reset();

Expect an element by xpath to have specific text

After pressing a save button a box will pop up and say if it was success or failed. The box has the same xpath no matter the result.
expect(element(by.xpath('path example')));
Inside the HTML for the element it says
<div class="panc lm-he" style="....."><span style="..."> Saved!</span></div>
edit -- oops it's early.
I want to know how can I have the expect come back true if the text "Saved!" is there or not. So if "Saved!" is present inside that element then it's true otherwise it's false.
Try with showing the output of the entire element like this:
element(by.xpath('path example')).then(function(element){
console.log(element);
});
not sure I understand want you want, but this way you will check if div with 'Saved!' text is Displayed
expect(element(by.xpath('.//div[text(), "Saved!"]')).isDisplayed).toBe(true);
As #Gunderson notes it doesn't matter what locator you use, the syntax will be the same. When I want to confirm text in an element I usually do something like this:
myElement.getText().then(function (text) {
expect(text).toContain(message)
});
That way you can tell by looking at the failure if the element didn't show up at all, or if it is visible but the text is not displayed, or if everything is fine and the test passes. So in your case it would just be
element(by.xpath('path example')).getText().then(function (text) {
expect(text).toContain('Saved!')
});

How can I select the first option inside a dropdown menu by targeting css?

I'm currently using Cucumber / Selenium / Ruby to create my automation framework and setup my first test. The one I'm working on involves me to fill in a form in order to proceed to the next stage. The form contains a dropdown with multiple values, of which I want to select one (and any one!)
Inspect Element of the Dropdown Menu
<input type="search" class="ember-power-select-trigger-multiple-input" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" id="ember-power-select-trigger-multiple-input-ember3325" aria-controls="ember-power-select-options-ember3325" style="width: 100%;" placeholder="All classes">
I've therefore made use of the class inside my step below:
My Step
#wait.until {#driver.find_element(:css => 'input.ember-power-select-trigger-multiple-input').click}
At the moment, when I run this, it's able to find the correct dropdown option and click it. The options in the list appear, but obviously nothing happens.
What I'd like to know is how I can extend this further so that the dropdown is selected, and that the "first" option is selected? I don't want to specify what it should be, but it just should randomly select the first from the list and use that.
Any thoughts on the easiest way to achieve this?
Research Snippet
I did some research and found the following snippet which I thought I could add to my code, however I'm unsure if it would actually work, or whether I could use this in conjunction with the #wait.until step that I mentioned above?
groupDropdown = #driver.find_element(:css => 'input.ember-power-select-trigger-multiple-input')
option = groupDropdown.find_element(:css, "option:nth-child(1)")
option.click
#wait.until {#driver.find_element(:css => 'input.ember-power-select-trigger-multiple-input').click}
#wait.until {#driver.find_element(:css => '.ember-view > li > .ember-view > li:nth-of-type(1) > .ember-view > li').click}
This worked.
Until
The “until” method within Selenium requires a “truthy” response to continue with the rest of the code.
What you could do is this:
power_select = #driver.find_element(:css => 'input.ember-power-select-trigger-multiple-input')
#wait.until {power_select.displayed?}
power_select.click
This will wait for the element to be displayed on the page, which returns a boolean, and then follow through with a click
Select
Following on from that, the methods for Selects are hidden within the library quite well, but after searching around for a bit:
To Select by text:
Selenium::WebDriver::Support::Select.new(#driver.find_element(:css => <insert_css_of_select_here>)).select_by(:text, <insert_option_text_here>)
To Select by index:
Selenium::Webdriver::Support::Select.new(#driver.find_element(:css => <insert_css_of_select_here>)).select_by(:index, <insert_index_value_here>)
Selecting by index is what you most likely want to do here, setting the index value to 0 to select the first option.
This will let you select required option of ember-power-select with Capybara:
find('.ember-power-select-trigger').click # Open trigger
find_all('ul.ember-power-select-options > li')[1].click # Select 2nd option
Tested with latest ember-power-select.
You might find the click be quite slow if your Capybara.default_max_wait_time is high, so to speed things further you can do this:
find('.ember-power-select-trigger').click # Open trigger
Capybara.using_wait_time(0.1) do
find_all('ul.ember-power-select-options > li')[1].click # Select 2nd option
end

Resources