How to check the Radio Button in Cypress. The regular check() is not working - reactjs

I bumped into a problem with Cypress. I just couldn't check the radio button.
I have 7 questions with Yes or No radio buttons. By default, all buttons are checked to "NO". I need to check the "YES" options, it will send an API call to the backend and continue to do magic.
The html code for YES looks like this:
<input type="radio" id="options[0]radiovalue-true" class="form-control is-action-field form-check-input" value="true" style="opacity: 0; cursor: pointer; height: 0px; width: 0px;">
The html code for NO looks like this:
<input type="radio" id="options[0]radiovalue-false" class="form-control is-action-field form-check-input" value="false" checked="" style="opacity: 0; cursor: pointer; height: 0px; width: 0px;">
By default the NO radio button has property: checked: true , the YES radio button has property: checked: false
This is my tries:
cy.get('[class="sc-fzoJMP"]')
.find('.list-group-item')
.then((item) => {
cy.wrap(item)
.eq(0)
.should('contain', 'Is this opportunity?')
.find('input[type="radio"]')
.then((radioButtons) => {
cy.wrap(radioButtons).eq(0).check({ force: true }).should('be.checked');
});
I used different locators, tried ('[type="radio"]'), (':radio'), ('#options[0]radiovalue-true') I used different check methods: cy.get(':radio').click({force: true}) , cy.get(':radio').check('true', {force: true}) and tried to move code with checking radio buttons out of the loop but this is something else. It doesn't check the radio button but can verify that it's not checked.
I found one solution to use invoke property:
cy.wrap(radioButtons).eq(0).invoke('prop', 'checked', true).should('be.checked');
cy.wrap(radioButtons).eq(1).invoke('prop', 'checked', false).should('not.be.checked');
But it's checking "YES" radio button but it's not unchecking "NO" radio button and it doesn't send API call to the backend as supposed to do.
This is full HTML code for YES and NO radio buttons:
<div class="d-flex ">
<div class="mr-4" style="position: relative;">
<div class="form-check">
<input type="radio" id="options[0]radiovalue-true" class="form-control is-action-field form-check-input" value="true" style="opacity: 0; cursor: pointer; height: 0px; width: 0px;">
<label for="options[0]radiovalue-true" class="ml-0 form-check__radio form-check-label">
<svg viewBox="0 0 24 24" style="height: 20px; min-height: 20px; width: 20px; min-width: 20px; opacity: 1;">
<title>Select Option</title>
<circle cx="12" cy="12" r="9" stroke="#666666" stroke-width="2" fill="white"></circle>
</svg>
<p class="sc-fznyAO hdDwJr ml-1 typography-body ">Yes</p>
</label>
</div>
</div>
<div class="mr-4" style="position: relative;">
<div class="form-check">
<input type="radio" id="options[0]radiovalue-false" class="form-control is-action-field form-check-input" value="false" checked="" style="opacity: 0; cursor: pointer; height: 0px; width: 0px;">
<label for="options[0]radiovalue-false" class="ml-0 form-check__radio form-check-label">
<svg viewBox="0 0 24 24" style="height: 20px; min-height: 20px; width: 20px; min-width: 20px; opacity: 1;">
<title>Selected Option</title>
<circle cx="12" cy="12" r="9" stroke="var(--dcp-color-primary)" stroke-width="2" fill="none"></circle>
<circle cx="12" cy="12" r="5" fill="var(--dcp-color-primary)"></circle>
</svg>
<p class="sc-fznyAO hdDwJr ml-1 typography-body ">No</p>
</label>
</div>
<div class="action-field-wrapper is-action-field"></div>
</div>
</div>

The id's that have been assigned contain characters that don't work with # notation, but you can use attribute notation
cy.get('.list-group-item')
.eq(0)
.find('[id="options[0]radiovalue-true"]') // query id as an attribute
.click()
cy.get('.list-group-item')
.eq(0)
.find('[id="options[0]radiovalue-false"]')
.click()
Specifically, the [] in the ids stops '#options[0]radiovalue-true' from working.
With the expanded fragment, this works
cy.get('input[id="options[0]radiovalue-true"]')
.click({force:true})
.should('be.checked')
You need force:true because of the style opacity:0 and width & height 0.
This means the input is effectively hidden, and there is probably a better way to test this - perhaps clicking on the SVG icons.

You can use the IDs and click to select the 'Yes' or 'No' radio buttons.
cy.get('.list-group-item')
.eq(0)
.find('#options[0]radiovalue-true')
.click() //Clicks Yes
cy.get('.list-group-item')
.eq(0)
.find('#options[0]radiovalue-false')
.click() //Clicks No

Related

FA Icon in placeholder of an input?

As I saw in the documentation, Font Awesome has a way of put an icon in an input placeholder, doing something like this:
<Input placeholder=' Search' />
This is what I get:
No matter what code I put after &#x, it always renders the same icon.
I'm working with ReactJS and Reactstrap library. Any suggestion? Thanks a lot (sorry 4 my english)
You can't do it this way, because the font family of the input field is using an English font. Font Awesome uses it's own font file.
One way to implement this would be to use a positioned <i> element:
<div class="container">
<label><b>Username</b></label>
<input type="text" placeholder="Enter Username" name="uname" required>
<i class="fa fa-user fa-lg"></i>
</div>
.container {
position: relative;
}
.container i {
position: absolute;
left: 15px;
top: 40px;
color: gray;
}

Select a value from input combo box using Selenium using xpath for a reachjs control

Hi Need to select "New South Wales" using By.xpath() any suggestions please?
This is a reactjs page jedwatson.github.io/react-select
<div class="Select-control">
<span class="Select-multi-value-wrapper" id="react-select-2--value">
<div class="Select-value State-NSW">
<span class="Select-value-label" role="option" aria-selected="true" id="react-select-2--value-item">New South Wales</span>
</div>
<div class="Select-input" style="display: inline-block;">
<input role="combobox" aria-expanded="false" aria-owns="" aria-haspopup="false" aria-activedescendant="react-select-2--value" value="" style="width: 5px; box-sizing: content-box;">
<div style="position: absolute; top: 0px; left: 0px; visibility: hidden; height: 0px; overflow: scroll; white-space: pre; font-size: 14px; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-weight: normal; font-style: normal; letter-spacing: normal;"></div>
</div>
</span>
<span class="Select-clear-zone" title="Clear value" aria-label="Clear value">
<span class="Select-clear">×</span>
</span>
<span class="Select-arrow-zone">
<span class="Select-arrow"></span>
</span>
</div>
Tried with the below code without success
driver.findElement(By.xpath("//input[#role='combobox'][#value='New York"']")).click();;
Below exception was observed
org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"xpath","selector":"//input[#role='combobox'][#value='New York']"}
(Session info: chrome=59.0.3071.86)
Please follow the below step to select your desired element
Click on the down arrow of dropdown
Select the desired option
Here is the code for same :
driver.findElement(By.xpath("//h3[contains(text(),'States')]/..//span[#class='Select-arrow']")).click();
driver.findElement(By.id("react-select-2--option-1")).click();
Updated
Use the below method to select the value dynamically based on text :
public void selectCombo(String valueText)
{
driver.findElement(By.xpath("//h3[contains(text(),'States')]/..//span[#class='Select-arrow']")).click();
WebElement dropdownValue = driver.findElement(By.xpath("//div[contains(text(),'"+valueText+"')]"));
dropdownValue.click();
}
Call this method from your code and pass the value which you want to select
e.g.
new TestClass().selectCombo("Tasmania");
You can try with the xpath //*[#role="option" and text()='New South Wales']

Draw colored dots in AngularJS

i saw this in a angularJS App:
Maybe he's drawing borders?? Any ideas how i could do this properly?
The color should be changeable.
I made a plunker where you can change the color of the dot with ngStyle, please take a look at it.
Using ngStyle you can also change the background-color within a controller.
HTML code:
<body ng-app="">
<input type="button" value="change color to blue" ng-click="myStyle={'background-color':'blue'}">
<input type="button" value="change color to red" ng-click="myStyle={'background-color':'red'}">
<div class="circle" ng-style="myStyle"></div>
</body>
CSS code:
.circle {
height: 20px;
width: 20px;
background-color: red;
border-radius: 10px;
}

how can I create a search box like Facebook's or WhatsApp's? (Mobile)

Is there a way to do that manually ? I was trying to use Ionic Framework, they had an attribute for that but is deprecated now.
By Facebook's/WhatsApp's search box I mean:
1 - Hidden at first sigh
2 - If you want to see it you have to pull down
3 - Once you focus on it, it extends up to the top of the screen and overlaps the header
4 - Has a button which is an X to delete the content of the search box and other button named "Cancel" to close the search box.
Pretty sure everyone has notice that behavior already.
So, what are the techniques to implement it ?
I am using Angular so I do not know if there is a way to do a Directive, or just with css ? what are your suggestions ?
something like this
it would be too time consuming for me to realize the all thing. but is not so difficoult if you are familiar with " transitions " in css3.
here is a "lite version"
var searchbox={
topPos_open:0, topPos_close:-50, isOpen:false,
open:function(){
var box=document.getElementById("searchbox");
box.style.top=this.topPos_open+"px";
document.getElementById("searchfield").focus();
this.isOpen=true;
},
close:function(){
var box=document.getElementById("searchbox");
box.style.top=this.topPos_close+"px";
this.isOpen=false;
},
pop:function(){
!this.isOpen?this.open():this.close();
},
clear:function(){
document.getElementById("searchfield").value="";
}
}
#searchbox{position:fixed; top:-50px; left:0px; width:100%; height:60px; background-color:rgba(135, 206, 235, 1); -webkit-transition:top 0.5s ease 0s; -moz-transition:top 0.5s ease 0s; transition:top 0.5s ease 0s;}
#searchbox input{border:0px none; margin:0px 10px 0px 10px; padding:0px; width:80%; font-size:20px;}
#searchbox #input{float:left; background-color:rgba(255, 255, 255, 1); border:1px solid #dddddd; border-radius:20px; margin:5px; padding:5px; width:70%; min-width:250px;}
#searchbox #close{float:right; padding:10px:}
#searchbox button{border:0px none; background-color:transparent; font-size:20px; cursor:pointer;}
#searchbox #dots{clear:both; text-align:center; font-size:25px; cursor:pointer;}
<div id="searchbox">
<div id="input">
<input type="text" id="searchfield" value="">
<button type="button" onclick="searchbox.clear()">
X
</button>
</div>
<div id="close">
<button type="button" onclick="searchbox.close()">
Cancel
</button></div>
<div id="dots" onclick="searchbox.pop()">
......
</div>
</div>
<br>
<br>
<br>
<br>
Click the dots

ng-click first apply class, then execute function

I have a shopping cart (a rootScope array) which gets turned into a list of items in it, including a button to delete that item from the cart array (the red X).
I don't have enough reputation to add an image, so here's a link to what it looks like
What I want to have happen is when I click one of the red X buttons, the item first does an animation(some sort of fade out), and then the actual cart has the item spliced from it. Using ng-click I am able to either do one or the other, but not both. When both is applied the animation doesn't trigger because it doesn't have time to. Is there a way to wait for the animation to finish, then perform the function?
(the animation executed by applying a class to the div on ng-click, so possibly a watch for class change?)
Here's my code. The code won't work in the snippet but you can see my functions and html.
$scope.removeFromCart = function(removedGame) {
index = $rootScope.cartArray.indexOf(removedGame);
$rootScope.cartArray.splice(index, 1);
};
$(".disappear").hasClass('fadeOutRight')(function(){
$scope.removeFromCart(cartArray[0]) ;
});
.cartGameDiv {
height: 140px;
width: auto;
}
<div ng-repeat = "newGame in cartArray" ng-class="disappear">
<div>
<div class="col-sm-11 col-lg-11 col-md-11 cartGameDiv">
<div class="thumbnail">
<div class="pull-left">
<img style="height: 100px; width: 213px; padding: 5px; margin-top: 5px" src="{{newGame.thumbnail}}" alt="">
<div id="ratingDiv" style="margin-left: 8px; margin-right: 8px; margin-bottom: 5px;">
<div style="display: inline-block" ng-bind-html="getTrustedHtml(newGame)"></div>
<p class="pull-right" style="color: #d17581">{{newGame.numberReviews}} reviews</p>
</div>
</div>
<div class="caption">
<h4 style="margin-top: 0" class="pull-right">{{newGame.price}}</h4>
<h4 style="margin-top: 0"><a class="categoryGameName" href="#details/{{myGamesList.indexOf(newGame)}}">{{newGame.name | removeSubName}}</a>
</h4>
<p>{{newGame.description.substring(0,290) + '...'}}</p>
</div>
</div>
</div>
</div>
<div class="col-sm-1 col-lg-1 col-md-1 cartGameDiv">
<img style="margin-bottom: 10px; margin-top: 10px;" src="images/glyphIconCheckmark.png" alt=""/>
<img ng-click="disappear='animated fadeOutRight'; removeFromCart(newGame)" style="margin-bottom: 10px" src="images/glyphIconRemoveGame.png" alt=""/>
<img src="images/glyphIconLike.png" alt=""/>
</div>
</div>
If you have any idea how to delay the function call until after the animation I'd really appreciate it! Thanks!
This is very simple to do using ngAnimate. Add the ngAnimate script to your page (you can get this from numerous CDNs), include ngAnimate as a dependency to your module and then just add some simple CSS.
.ng-leave{
-webkit-animation: fadeOutRight 1s;
-moz-animation: fadeOutRight 1s;
-o-animation: fadeOutRight 1s;
animation: fadeOutRight 1s;
}
In your example, you need not do any work applying the class yourself, ngAnimate will do it for you.
Here is a Plunker demonstrating how you would do it.

Resources