handle vue-js dropdown plugin in selenium webdriver - selenium

I am testing a web application which has v-select vuejs dropdown plugin for Country field. How Can I select values in dropdown using selenium webdriver.
It has no select/div.
Below is the HTML before selecting the country from the dropwdown
<div data-v-ce984332="" id="country-fg" class="mg-t-20">
<p data-v-ce984332="" class="control has-icon has-icon-right">
<div data-v-ce984332="" dir="auto" class="dropdown v-select single searchable" name="country" aria-required="true" aria-invalid="false">
<div class="dropdown-toggle clearfix">
<input type="search" autocomplete="false" placeholder="Country" aria-label="Search for option" class="form-control" style="width: 100%;"> <button type="button" title="Clear selection" class="clear"><span aria-hidden="true">×</span></button> <i role="presentation" class="open-indicator"></i>
<div class="spinner" style="display: none;">Loading...</div>
</div>
<!---->
</div>
<span data-v-ce984332="" class="small tx-warning" style="display: none;"></span></p>
</div>
And this is the HTML after selecting the country as United States from the dropdown
<div data-v-ce984332="" id="country-fg" class="mg-t-20">
<p data-v-ce984332="" class="control has-icon has-icon-right">
<div data-v-ce984332="" dir="auto" class="dropdown v-select single searchable" name="country" aria-required="true" aria-invalid="true">
<div class="dropdown-toggle clearfix">
<span class="selected-tag">
United States
<!---->
</span>
<input type="search" autocomplete="false" aria-label="Search for option" class="form-control" style="width: auto;"> <button type="button" title="Clear selection" class="clear"><span aria-hidden="true">×</span></button> <i role="presentation" class="open-indicator"></i>
<div class="spinner" style="display: none;">Loading...</div>
</div>
<!---->
</div>
<span data-v-ce984332="" class="small tx-warning" style="display: none;"></span></p>
</div>

Please specify the language binding you are using and the things you've tried so far.
Algo in Java:
click the 'dropdown' field: driver.findElement(By.name("country")).click()
click the option: driver.findElement(By.name("country-1")).click()
These kinds of 'dropdown' fields are usually tied to another div / element.
E.g., when you click the 'dropdown' field (item 1), another dynamic div may appear containing the options in some form of tag.
Most common examples would be, <li>, <div>, <span>. You'll then have to do another click() on the option you want. (item 2)
There are even cases where the dropdown div encloses an input tag to which you can do sendKeys() or setAttribute() as well as cases where you can do a javascript click directly into one of the options.
Suggest you provide more info so we can help you better.
selenium language bindings
html snippet of the dropdown - please avoid using screenshots for snippets
html element of the options that appear when you click the dropdown

Related

Find element where doesn't contains a specific class

I have two objects on the page with same html. Only one of the element's parent tag doesn't have same class name. When I try using not(contains()) it still shows both elements
below is the xpath I tried and still it is detecting both buttons and always clicking on the second button.
//div[contains(#class,"jss") and
not(contains(#class,"canvas-image-export"))]//button[contains(.,'Connected')]
below is the code for first button named Connected where I am interested to get
<div class="jss203">
<div class="MuiTabs-root jss244">
<div class="MuiTabs-scroller MuiTabs-fixed" style="overflow: hidden;">
<div class="MuiTabs-flexContainer" role="tablist">
<button class="MuiButtonBase-root MuiTab-root MuiTab-textColorPrimary Mui-selected" tabindex="0" type="button" role="tab" aria-selected="true"><span class="MuiTab-wrapper">Overview</span><span class="MuiTouchRipple-root"></span></button>
<button class="MuiButtonBase-root MuiTab-root MuiTab-textColorPrimary" tabindex="-1" type="button" role="tab" aria-selected="false"><span class="MuiTab-wrapper">Data Sources</span><span class="MuiTouchRipple-root"></span></button>
<button class="MuiButtonBase-root MuiTab-root MuiTab-textColorPrimary" tabindex="-1" type="button" role="tab" aria-selected="false"><span class="MuiTab-wrapper">Connected</span><span class="MuiTouchRipple-root"></span></button>
</div>
</div>
</div>
</div>
below is the code for second button named Connected which I should not click on
<div class="jss197 canvas-image-export">
<span class="" data-testid="componentContainer">
<div class="MuiTabs-root jss244">
<div class="MuiTabs-scroller MuiTabs-fixed" style="overflow: hidden;">
<div class="MuiTabs-flexContainer" role="tablist">
<button class="MuiButtonBase-root MuiTab-root MuiTab-textColorPrimary Mui-selected" tabindex="0" type="button" role="tab" aria-selected="true"><span class="MuiTab-wrapper">Overview</span><span class="MuiTouchRipple-root"></span></button>
<button class="MuiButtonBase-root MuiTab-root MuiTab-textColorPrimary" tabindex="-1" type="button" role="tab" aria-selected="false"><span class="MuiTab-wrapper">Data Sources</span><span class="MuiTouchRipple-root"></span></button>
<button class="MuiButtonBase-root MuiTab-root MuiTab-textColorPrimary" tabindex="-1" type="button" role="tab" aria-selected="false"><span class="MuiTab-wrapper">Connected</span><span class="MuiTouchRipple-root"></span></button>
</div>
</div>
</div>
</span>
</div>
TIA
Your problem here is that you are looking on the upper parent node <div class="jss197 canvas-image-export"> vs <div class="jss203"> while there is another element there <div class="MuiTabs-root jss244"> or <div class="MuiTabs-root jss244"> and it is also matching your XPath //div[contains(#class,"jss") and not(contains(#class,"canvas-image-export"))]//button[contains(.,'Connected')].
So, to make your XPath work you need to add one more detail: not contains MuiTabs-root class, as following:
//div[contains(#class,"jss") and not(contains(#class,"canvas-image-export")) and not(contains(#class,"MuiTabs-root"))]//button[contains(.,'Connected')]
To get only first div buttons, you can exclude the span tag for the second element. Using following xpath you can get that.
//div[starts-with(#class,'jss')][not(span[#data-testid='componentContainer'])]//button[contains(.,'Connected')]
Or
//div[starts-with(#class,'jss')][not(span)]//button[contains(.,'Connected')]

Vuetify and Screenreader issue - label of v-select isn't read

I am actually using Vuetify 2.6.6, sticking to the standard components.
Beeing asked to make it accessible for screen reader users I struggle with the label not read by NVDA in case of v-select. (it must be read on hovering the label)
<v-select :items="items" label="name">
</v-select>
I already played around with some of the examples on https://vuetifyjs.com/en/features/accessibility/ but nothing really helps.
Interesting: Not even the examples on the vuetifyjs site are read.
Also: Clicking in the input field makes NVDA read the label. Unfortunately, having selected sth. it says nothing is selected or blank.
Having finally selected sth. and hovering an inch to the right of the label... it is read.
The items in the v-select are just an array of strings.
If I understood right, semantic tags like label and input do not need to have additional aria attributes but my knowledge in this field is limited.
However, this is what gets rendered:
<div class="v-input theme--light v-text-field v-text-field--is-booted v-select">
<div class="v-input__control">
<div role="button" aria-haspopup="listbox" aria-expanded="false" aria-owns="list-14" class="v-input__slot">
<div class="v-select__slot">
<label for="input-14" class="v-label theme--light"
style="left: 0px; right: auto; position: absolute;">Name</label>
<div class="v-select__selections"><input id="input-14" readonly="readonly" type="text"
aria-readonly="false" autocomplete="off" control-id="ControlID-2"></div>
<div class="v-input__append-inner">
<div class="v-input__icon v-input__icon--append">
<i aria-hidden="true" class="v-icon notranslate mdi mdi-menu-down theme--light"></i>
</div>
</div>
<input type="hidden">
</div>
<div class="v-menu">
<!---->
</div>
</div>
<div class="v-text-field__details">
<div class="v-messages theme--light">
<div class="v-messages__wrapper"></div>
</div>
</div>
</div>

inline style for Div or span not making element inline

I have a bootstrap3 navbar. The navbar has a login form on the right and login and signup buttons. I want that once the user logs in successfully, these controls disapper and signup and profile links come up (and vice versa when the user clicks sign out). I am able to do this using [hidden]="someValue" but I suppose using hidden is not the right approach. I thought of doing it using *ngIf but my issue is that the login form and sign up buttons appear in separate lines and not in single line. I tried using <div> with inline style and also <span> but it didn't work
<div *ngIf = "userNotloggedIn" [ngStyle]="{display: inline}"> <!--tried span as well but it didnt' work either-->
<li ><!-- Navbar Form --> <!-- Instead of ngIf, if I use [hidden]="!userNotloggedIn" for each li then it works but I want to use ngIf-->
<form class="form-inline" [formGroup]="loginForm" (ngSubmit)="signInUser()" novalidate>
<label for="username" class="control-label required sr-only">Username</label>
<input type="text" id="username" class="form-control" placeholder="username" formControlName="userName" [ngClass]="validateField('userName')" required>
<app-show-errors [control]="loginForm.controls.userName"></app-show-errors>
<label for="password" class="control-label required sr-only">Password</label>
<input type="password" id="password" class="form-control" placeholder="password" formControlName="password" [ngClass]="validateField('password')" required>
<app-show-errors [control]="loginForm.controls.password"></app-show-errors>
<button type="submit" id="login-button" class="btn content-div__button--blue btn-sm">Sign In</button>
</form>
</li>
<li class="nav-item" > <!-- [hidden]="!userNotloggedIn" works-->
<a class="nav-link" [routerLink]="signupRouterLink">Sign Up</a>
</li>
</div>
<div *ngIf="!userNotloggedIn" [ngStyle]="{display: inline}">
<li class="nav-item" > <!-- [hidden]="userNotloggedIn" works-->
<a [routerLink]="" (click)="onProfileClick()">My Profile</a>
</li>
<li class="nav-item" > <!-- [hidden]="userNotloggedIn" works -->
<a [routerLink]="" (click)="onSignoutClick()">Sign out</a>
</li>
</div>
I was able to solve my problem using ng-container instead of div or span but I don't know why div or span didnt work. Happy to accept answers which can explain this.

I am not able to click radiobuttons using Robot Framework.(and selenium2Library)

Could anyone help me out please?
Actually, the radiobuttons are always in the DOM but they are visible on the page based on ADDRESS field, so as you can see below if Pickup and Delivery timezone are same then the radiobuttons are not visible on page:
but if they(pickup and delivery timezone) are different then the RADIO BUTTONS are visible as shown below:
.
Now in my script I try to set all the radiobuttons as NO, so when I run it the script passes but in real the radiobuttons are left untouched. The result is PASS as shown below
and Chrome browser after the script run is shown below:
Here is the script I wrote for waiting and clicking on radiobuttons:
`wait until element is enabled id=exportclearance_1
page should contain radio button id=exportclearance_1
click element id=exportclearance_1
click element id=transitclearance_1
click element id=importclearance_1
click element id=insurance_1`
Here is the HTML of page:
`<div class="form-group">
<label class="col-sm-4 control-label" for="">
<div class="col-sm-6">
<input id="exportclearance_0" name="export_clearance" value="True" autocomplete="off" type="radio"/>
<label class="control-label control-label-light clearance" for="exportclearance_0">Yes</label>
<input id="exportclearance_1" name="export_clearance" value="False" autocomplete="off" type="radio"/>
<label class="control-label control-label-light clearance" for="exportclearance_1">No</label>
<br/>
</div>
</div>
<div id="exportclearance-textarea" style="display:none">
<div class="row col-sm-6 col-sm-offset-4">
<textarea id="field-exportclearance" class="form-control customs-field" cols="40" name="export_clearance_instructions" placeholder="Instructions for export clearance (E.g. Broker details, Customs number, etc.)" rows="2"/>
</div>
</div>
<div class="form-group">
<div id="transitclearance-textarea" style="display:none">
<div class="form-group">
<div id="importclearance-textarea" style="display:none">
</div>
<div class="form-group">
<div id="id_attachment_formset_parent">
<div class="form-group">
<di
`
JavaScript executor worked for me as given below.
execute javascript document.getElementById('insurance_1').click()

identifying clustered element from a html page using selenium

I want to identify the following element but unable to do so.
<fieldset class="ng-scope" ng-if="permissions.isEditable && (permissions.isApprover || permissions.isReviewer)">
<div class="row">
<div class="small-12 columns">
<div class="label-container">
<label>Reviewer comments <a class="tooltip-item" href="javascript:void(0);">[?]
<div class="tooltip">
<p>Contents of the comment
can be viewed by Immigration
team and employee who logged
the request.</p>
</div>
</a>
</label>
</div>
<div class="value-container">
<textarea name="Comments" class="required-on-send-back required-on-hold required-on-reject ng-pristine ng-untouched ng-valid" ng-model="requisitionRequest.request.reviewerComments" rows="4"></textarea>
</div>
</div>
</div>
</fieldset>
Note there are 3 fieldset above as well .
You can write a css selector based on the fieldset attributes like:
fieldset[ng-if*='isApprover'][ng-if*='isReviewer'][ng-if*='isEditable']
You can remove any of the [] condition block.
This xpath should help in identifying the fieldset:
//fieldset[.//textarea[#name='Comments']]