How to use XPath to Find this locater Dynamically - selenium

I am trying to find checkbox element with dynamic XPath, I couldn't figure it out Is there anyone can help me?
<tr>
<td>
***<span style="font-weight: bold;">Text Message</span>***
</td>
<td>
<div id="landingzone_form:j_id_94">
<div id="landingzone_form:j_id_95" class="ui-selectbooleancheckbox ui-chkbox ui-widget">
<div class="ui-helper-hidden-accessible">
<input id="landingzone_form:j_id_95_input" name="landingzone_form:j_id_95_input" type="checkbox" autocomplete="off" aria-hidden="true" aria-checked="false" onchange="PrimeFaces.ab({s:"landingzone_form:j_id_95",e:"change",f:"landingzone_form",p:"landingzone_form:j_id_95",fi:"landingzone_form:j_id_94"});">
</div>
<div class="ui-chkbox-box ui-widget ui-corner-all ui-state-default">
***<span class="ui-chkbox-icon ui-icon ui-icon-blank ui-c"></span>***
</div>
</div>
</div>
</td>
</tr>
I am trying to find "" this element from "Text Message". Thank you

Perhaps something like this:
//tr[contains(., 'Text Message')]//span[contains(#class, 'ui-chkbox-icon')]"

You can try this to locate the checkbox by using the css selector
driver.findElement(By.cssSelector(".ui-chkbox-icon.ui-icon.ui-icon-blank.ui-c")).click();

Related

select2 dropdown with selenium

I have a drop down in WordPress products page which is a select2 ajax enabled.
I have managed to show the options in the drop down using selenium.
But i am not able to select one of the options from the list.
I am able to get the element using the below code. But the element is not castable to Select nor clickable.
driver.findElement(By.cssSelector("[class='multiselect attribute_values wc-enhanced-select select2-hidden-accessible enhanced']"))
Any ideas how to select any option from it?
The HTML code for the drop down is
<tr>
<td class="attribute_name">
<label>Name:</label>
<strong>Brand</strong>
<input type="hidden" name="attribute_names[0]" value="pa_brand">
<input type="hidden" name="attribute_position[0]" class="attribute_position" value="0">
</td>
<td rowspan="3">
<label>Value(s):</label>
<select multiple="" data-placeholder="Select terms" class="multiselect attribute_values wc-enhanced-select select2-hidden-accessible enhanced" name="attribute_values[0][]" tabindex="-1" aria-hidden="true">
<option value="107">Adidas</option>
<option value="110">Gul Ahmed</option>
<option value="111">Khadi</option>
</select>
<span class="select2 select2-container select2-container--default select2-container--above select2-container--open" dir="ltr" style="width: auto;">
<span class="selection">
<span class="select2-selection select2-selection--multiple" aria-haspopup="true" aria-expanded="true" tabindex="-1" aria-owns="select2-attribute_values0-to-results" aria-activedescendant="select2-attribute_values0-to-result-d16b-111">
<ul class="select2-selection__rendered" aria-live="polite" aria-relevant="additions removals" aria-atomic="true">
<li class="select2-search select2-search--inline"><input class="select2-search__field" type="text" tabindex="0" autocomplete="off" autocorrect="off" autocapitalize="none" spellcheck="false" role="textbox" aria-autocomplete="list" placeholder="Select terms" style="width: 418.797px;" aria-owns="select2-attribute_values0-to-results" aria-activedescendant="select2-attribute_values0-to-result-d16b-111"></li>
</ul>
</span>
</span>
<span class="dropdown-wrapper" aria-hidden="true"></span>
</span>
<button class="button plus select_all_attributes">Select all</button>
<button class="button minus select_no_attributes">Select none</button>
<button class="button fr plus add_new_attribute">Add new</button>
</td>
</tr>
As per the HTML:
<select multiple="" data-placeholder="Select terms" class="multiselect attribute_values wc-enhanced-select select2-hidden-accessible enhanced" name="attribute_values[0][]" tabindex="-1" aria-hidden="true">
The WebElement is clearly a <select> node and to select one of the options from the html-select tag you need to induce WebDriverWait for the elementToBeClickable() and you can use either of the following locator strategies:
Using cssSelector and selectByVisibleText():
new Select(new WebDriverWait(driver, Duration.ofSeconds(10)).until(ExpectedConditions.elementToBeClickable(By.cssSelector("select.multiselect.attribute_values.wc-enhanced-select.select2-hidden-accessible.enhanced[data-placeholder='Select terms']")))).selectByVisibleText("Adidas");
Using xpath and selectByValue():
new Select(new WebDriverWait(driver, Duration.ofSeconds(10)).until(ExpectedConditions.elementToBeClickable(By.xpath("//select[#class='multiselect attribute_values wc-enhanced-select select2-hidden-accessible enhanced' and #data-placeholder='Select terms']")))).selectByValue("110");

Not able to check the check box, exception "element not visible"

In an table which can contain more rows, user is searchable using the email id. After searching, selecting the first check box. But selenium is throwing the element not visible exception.
//*[#id='share_user']/tbody/tr1/td1//label
//*[#id='share_user']/tbody/tr1/td1//input
//label[#for='checkbox_416']
last identifier is dynamic. Still getting the element not visible exception.
Table code is mentioned below
<table class="table table-striped table-hover dataTable" id="share_user"
aria-describedby="share_user_info">
<thead>
<tr role="row">
<th class="small-cell sorting" role="columnheader" tabindex="0"
aria-controls="share_user" rowspan="1" colspan="1" style="width: 137px;"
aria-label="Share Profile : activate to sort column ascending">Share Profile </th>
<th class="medium-cell sorting" role="columnheader" tabindex="0"
aria-controls="share_user" rowspan="1" colspan="1" style="width: 523px;"
aria-label="User Details: activate to sort column ascending">User Details</th>
<th class="medium-cell sorting_asc" role="columnheader" tabindex="0"
aria-controls="share_user" rowspan="1" colspan="1" style="width: 366px;"
aria-sort="ascending" aria-label="Access: activate to sort column descending">Access</th>
</tr>
</thead>
<tbody role="alert" aria-live="polite" aria-relevant="all">
<tr class="odd">
<td class="">
<div class="checkbox check-default">
<input name="checkUser" id="checkbox_416" value="416" class="shareCheck"
type="checkbox">
<label for="checkbox_416"></label>
</div>
</td>
<td class=" ">
<img src="" class="img-responsive display-inline share-image">
<div class="display-inline">
<p class="share-name">alexx</p>
<p class="muted">
<i class="fa fa-envelope" hidden="true"></i>
<span>alexxm360#gmail.com</span>
</p>
</div>
</td>
<td style="vertical-align: middle;" class=" sorting_1">
<div class="select2-container medium-cell" id="s2id_rolelink416"
style="float:left;">
<a href="javascript:void(0)" onclick="return false;" class="select2-choice"
tabindex="-1">
<span class="select2-chosen">PROFILE ADMIN</span>
<abbr class="select2-search-choice-close"></abbr>
<span class="select2-arrow">
<b></b>
</span>
</a>
<input class="select2-focusser select2-offscreen" id="s2id_autogen11"
type="text">
<div class="select2-drop select2-display-none select2-with-searchbox">
<div class="select2-search">
<input autocomplete="off" autocorrect="off"
autocapitalize="off" spellcheck="false" class="select2-input"
type="text">
</div>
<ul class="select2-results">
</ul>
</div>
</div>
<select name="profileUsers.roleId" id="rolelink416"
class="medium-cell select2-offscreen" style="float:left;" tabindex="-1">
<option value="6">PROFILE ADMIN</option>
<option value="7">PROFILE AGENT</option>
<option value="8">PROFILE VIEWER</option>
<option value="196">profile role</option>
</select>
</td>
</tr>
</tbody>
</table>
providing the screen shots as well.
Try to use explicit wait with Expected Conditions
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement checkbox = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[#id='share_user']/tbody/tr[1]/td[1]//input")));
checkbox.click();
You can use the following expression, I have verified working fine.
driver.findElement(By.xpath("//*[#id='share_user']/tbody/tr[1]/td[1]/div")).click();
Try this
int ele_size=driver.findElements(By.xpath("locator")).size();
driver.findElements(By.xpath("locator")).get(ele_size-1).click();
We might encounter element not visible exception if element matching the locator existed in the DOM but is not currently visible. So we have to take the size of the element in first statement then in next statement we have to take the first element from the list and click on element.
Used this //*[#id='share_user']/tbody/tr[1]/td[1]/div worked

Is it possible for selenium to find a label element by its "for" attribute using xpath?

Is it possible for selenium to find a label element by its "for" attribute using xpath?
I'm testing a site that has 7 yes or no questions in row. The way the CSS is done, you click on the label instead of the input radio button. Normally I'd just find the element by text content, but there is a yes and no for each question.
I'm thinking that a work-around would be to do a javascript click on the input button to get around the "element is not visible" error that I get when trying to .click() the input directly, but I wanted to see if there was a better way to locate the label which is what users would actually be clicking.
*Edit for all of your who can't remember what a label element looks like. How would you select the middle one from this group?
<label for="superLongSetOfRandomCharacters123" class="common-to-all-buttons"> No </label>
<label for="superLongSetOfRandomCharacters345" class="common-to-all-buttons"> No </label>
<label for="superLongSetOfRandomCharacters456" class="common-to-all-buttons"> No </label>
More specifically, this is how they sit in the DOM
<ul class="list-view list-view-dividers">
<li class="list-view-item">
<div class="content">
<div id="variableValue1" class="multipleChoice">
<div class="form-row">
<label>Question 1</label>
<div class="form-row">
<table class="choices" id="randomlyGenerated-1">
<tbody>
<tr>
<td>
<div class="ui-radio"><label for="randomlyGenerated1" class="ui-btn ui-corner-all ui-btn-inherit ui-btn-icon-left ui-radio-off"> Yes</label><input id="randomlyGenerated1" type="radio" name="randomlyGenerated1" value="Yes"></div>
</td>
<td>
<div class="ui-radio"><label for="randomlyGenerated2" class="ui-btn ui-corner-all ui-btn-inherit ui-btn-icon-left ui-radio-off"> No</label><input id="randomlyGenerated2" type="radio" name="randomlyGenerated2" value="No"></div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="randomlyGenerated1-Error" class="component-error"></div>
</div>
</div>
</li>
<li class="list-view-item">
<div class="content">
<div id="variableValue2" class="multipleChoice">
<div class="form-row">
<label>Question 2</label>
<div class="form-row">
<table class="choices" id="randomlyGenerated-2">
<tbody>
<tr>
<td>
<div class="ui-radio"><label for="randomlyGenerated21" class="ui-btn ui-corner-all ui-btn-inherit ui-btn-icon-left ui-radio-off"> Yes</label><input id="randomlyGenerated21" type="radio" name="randomlyGenerated21" value="Yes"></div>
</td>
<td>
<div class="ui-radio"><label for="randomlyGenerated22" class="ui-btn ui-corner-all ui-btn-inherit ui-btn-icon-left ui-radio-off"> No</label><input id="randomlyGenerated22" type="radio" name="randomlyGenerated22" value="No"></div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="randomlyGenerated2-Error" class="component-error"></div>
</div>
</div>
</li>
</ul>
It works for selecting all labels with target 'for':
label[#for='superLongSetOfRandomCharacters123']
or you can leave #for='' blank for selecting all labels with any values (i.e. label[#for])
I guess, the XPath-Option you are looking for would be "#". so in your case something like [...]/label/#for would return you that for-value, which you could then use to check where you are ;)
Cheers
D
Use find_element_by_xpath
label = self.browser.find_element_by_xpath('//label[#for="id_field"]')

FileUpload with HtmlUnit doesn't fire fileUploadListener-Event (Primefaces auto upload)

I'm trying to automate a file-upload with WebDriver. It works fine for ChromeDriver and FirefoxDriver, but refuses to work for HTMLUnit.
I've already read
Using Webdriver for PrimeFaces file upload
https://stackoverflow.com/questions/21753497/unable-to-automate-filling-of-form-with-file-upload-using-htmlunit
Unable to upload file using Selenium web driver
but both were not helpfull.
The selenium (java)code for this upload-action is quiete simple:
String elementXPath = "//input[contains(#id,'FileUpload_input')]";
WebElement element = driver.findElement(By.xpath(elementXPath));
element.sendKeys(pathToFile);
The html-code of the inputElement is:
<div class="fileupload-buttonbar ui-widget-header ui-corner-top">
<label class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-icon-left fileinput-button" role="button" aria-disabled="false">
<span class="ui-button-icon-left ui-icon ui-icon-plusthick"></span>
<span class="ui-button-text">Upload</span>
<input type="file" id="form:FileUpload_input" name="form:FileUpload_input">
</label>
</div>
<div class="fileupload-content ui-widget-content ui-corner-bottom">
<table class="files"></table>
</div>
maybe necessary, the primefaces-codesnippet of the input-Element:
<div class="#{modalDialog ? 'span5' : 'span6'}">
<p:fileUpload id="FileUpload" mode="advanced" auto="true" sizeLimit="2097152" fileUploadListener="#{ClassView.handleFileUpload}"
label="Upload" allowTypes="/(\.|\/)(gif|GIF|jpe?g|JPE?G|png|PNG)$/" process="#this"
showButtons="false"/>
</div>
As you can see, it's a picure-Upload. The noteworthy characteristic of this upload is, that there is no 'confirm'- or 'submit'-button.
The testautomation works fine for the main-browsers, but fails with htmlUnit. After hours of debugging, I can confirm, that htmlUnit performs the 'sendKeys'-Methode, but this doesn't trigger the fileUploadListener. I already tried to click other Elements, so there is a focusLost-Action, but that didn't help.
Indeed, a 'driver.getPageSource()' after the 'sendKeys' delivers:
<div class="fileupload-buttonbar ui-widget-header ui-corner-top">
<label class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-icon-left fileinput-button" role="button" aria-disabled="false">
<span class="ui-button-icon-left ui-icon ui-icon-plusthick"></span>
<span class="ui-button-text">Upload</span>
<input id="form:FileUpload_input" name="form:FileUpload_input" value="correct\path\to\file\pic.png" type="file" >
</label>
</div>
<div class="fileupload-content ui-widget-content ui-corner-bottom">
<table class="files">
<tbody align="left">
<tr class="template-upload" style="">
<td class="preview"></td>
<td class="name">pic.png</td>
<td class="size"></td>
<td class="progress">
<div class="ui-progressbar ui-widget ui-widget-content ui-corner-all" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="100">
<div class="ui-progressbar-value ui-widget-header ui-corner-left ui-corner-right" style="width: 100%; display: block;"></div>
</div>
</td>
<td class="start">
<button class="ui-button ui-widget ui-state-default ui-corner-all ui-button-icon-only ui-state-hover" type="submit">
<span class="ui-button-icon-left ui-icon ui-icon ui-icon-arrowreturnthick-1-n"></span>
<span class="ui-button-text">ui-button</span>
</button>
</td>
<td class="cancel">
<button class="ui-button ui-widget ui-state-default ui-corner-all ui-button-icon-only">
<span class="ui-button-icon-left ui-icon ui-icon ui-icon-cancel"></span>
<span class="ui-button-text">ui-button</span>
</button>
</td>
</tr>
</tbody>
</table>
</div>
So there are now buttons...why?
I still tried to click the button with xPath "//td[#class='start']//button" but still nothing happend. No Fileupload.
HtmlDriver has javascript enabled and also I'm using NicelyResynchronizingAjaxController(). I already tried waiting for over 30 Seconds but still that doesn't work.
Is there someoone who knows this problem and it's solution...or at least a workaround?
I found the solution by myself.
I was still using selenium 2.40, upgrading to 2.42 solved the problem although the changelog didn't suggested a possible bugfix for my problem.

Selenium inside siblings

Is there a way to click further inside siblings in Selenium Webdriver? For example, here's the HTML:
<tr class="rich-table-row xx-datalist-even" onmouseover="Element.addClassName(this, 'xx-datalist-mouseover')" onmouseout="Element.removeClassName(this, 'xx-datalist-mouseover')">
<td class="rich-table-cell xx-datalist " id="userTableForm01:usersTableData:264:j_id102" style="text-align:center; width:20px;">
<img src="/static/images/graphics/status1.gif" title="Disabled" />
</td>
<td id="userTableForm01:usersTableData:264:col1" class="rich-table-cell xx-datalist">
<span id="userTableForm01:usersTableData:264:author_id">2377</span>
</td>
<td id="userTableForm01:usersTableData:264:col2" class="rich-table-cell xx-datalist">seleniumtest2312</td>
<td id="userTableForm01:usersTableData:264:col3" class="rich-table-cell xx-datalist">
<span style="margin-right:3px">Test2312</span>
Selenium
</td>
<td class="rich-table-cell xx-datalist " id="userTableForm01:usersTableData:264:col4" style="text-align:center;">
<input type="checkbox" name="userTableForm01:usersTableData:264:j_id111" onclick="A4J.AJAX.Submit('userTableForm01',event,{'similarityGroupingId':'userTableForm01:usersTableData:264:j_id112','parameters':{'userTableForm01:usersTableData:264:j_id112':'userTableForm01:usersTableData:264:j_id112'} } )" />
</td>
<td id="userTableForm01:usersTableData:264:col6" class="rich-table-cell xx-datalist">
<a id="userTableForm01:usersTableData:264:enable_link" href="#" style="margin-right:5px" onclick="if(typeof jsfcljs == 'function'){jsfcljs(document.getElementById('userTableForm01'),{'userTableForm01:usersTableData:264:enable_link':'userTableForm01:usersTableData:264:enable_link'},'');}return false">
<span id="userTableForm01:usersTableData:264:enable_link_text" class="xx-datalist">Enable</span>
</a>
<a id="userTableForm01:usersTableData:264:edit_link" href="#" style="margin-right:5px" onclick="if(typeof jsfcljs == 'function'){jsfcljs(document.getElementById('userTableForm01'),{'userTableForm01:usersTableData:264:edit_link':'userTableForm01:usersTableData:264:edit_link'},'');}return false">
<span id="userTableForm01:usersTableData:264:edit_link_text" class="xx-datalist">Edit</span>
</a>
<a id="userTableForm01:usersTableData:264:remove_link" href="#" onclick="if(typeof jsfcljs == 'function'){jsfcljs(document.getElementById('userTableForm01'),{'userTableForm01:usersTableData:264:remove_link':'userTableForm01:usersTableData:264:remove_link'},'');}return false">
<span id="userTableForm01:usersTableData:264:remove_link_text" class="xx-datalist">Delete</span>
</a>
</td>
</tr>
Now, this is a much bigger table than shown, so there are a lot more tr's with more users. The ID's are all auto-generated and different each time, and I am trying to click the 'Enable'-link, though the only thing unique on the same row that I can use is the username seleniumtest2312, which has brought me to this:
driver.findElement(By.xpath("//td[text()='seleniumtest2312']/following-sibling::td[3]/span[text()='Enable']")).click();
But it just won't work (no such element).
If there are better ways of solving this issue I'll be happy to try them.
The last part of your XPath is a bit off :
following-sibling::td[3]/span[text()='Enable']
because <span> you're looking for isn't direct child of <td>. You can try this XPath instead :
//td[.='seleniumtest2312']/following-sibling::td[3]/a/span[.='Enable']