My problem is very simple. I'm writing a Selenium test that MUST work with IE7. I have a HTML table with couple of rows and 3 columns:
Column 1 - contains a check box
Column 2 - contains a link
Column 3 - contains some free text
One (and ONLY one) of the checkboxes in the table is disabled. My task is to locate and click the link next to the disabled checkbox (on the row of the disabled checkbox). In FireFox this simple XPath expressions work fine:
//tr/td/input[#disabled]/../../td[2]/a
//tr/td/input[#disabled='disabled']/../../td[2]/a
But in IE7 the first expression clicks the top row no matter if the checkbox is enabled or disabled and the second one does not work.
Since the HTML document is very long I'm putting the important part below (as shown in FF):
<tr>
<td class="table_detail w e s center">
<input name="Delete_kG0KCgAMniwAAAEsxxgeUH0G" type="checkbox">
</td>
<td class="table_detail e s">
000000
</td>
<td class="table_detail e s">
some text
</td>
</tr>
<tr>
<td class="table_detail w e s center">
<input name="Delete_hooKCgAMi5AAAAEsFnQeUH0G" type="checkbox">
</td>
<td class="table_detail e s">
111111
</td>
<td class="table_detail e s">
</td>
</tr>
<tr>
<td class="table_detail w e s center">
<input disabled="disabled" type="checkbox">
</td>
<td class="table_detail e s">
400086
</td>
<td class="table_detail e s">
</td>
</tr>
The last link should be clicked:
400086
We use the Java Selenium API in JUnit 3 tests. The test is something like:
public void testSomething()
{
...
selenium.click("//tr/td/input[#disabled]/../../td[2]/a");
//wait to load and then test something on the page that is opened.
...
}
This works in FF but not in IE7. In IE7 it clicks the link on the first row as if disabled is ignored. It also evaluates correct in XPather (FF plugin).
I would appreciate your help.
Thanks!
You have shown the HTML in FireFox, but you haven't shown the HTML in IE, is it the same?
Based upon the information provided I would use this locator:
//tr[td/input[#disabled='disabled']]/td/a
This finds a row that has a cell that contains a disabled input element, and then locates the cell that has an achor and pinpoints the anchor.
However as I cannot see the HTML markup in IE I have no idea if this is valid or not
For the record I was able to resolve the problem by using a DOM locator. Unfortunately it looks as ugly as:
dom=function getLinkNextToDisabled()
{
var addressesTable = document.getElementsByName('AddressList')[0].getElementsByTagName('table')[0].getElementsByTagName('table')[0];
var inputs = addressesTable.getElementsByTagName('input');
for (i = 0; i < inputs.length; i++)
{
if (inputs[i].disabled)
{
return inputs[i].parentNode.parentNode.getElementsByTagName('a')[0];
}
}
};
getLinkNextToDisabled();
Unfortunately code like this makes me sad, so I'm still open for any XPath solution that will work in IE7.
Regards!
Related
The DOM my test application changes depending upon the window size. So I am trying to write an XPATH which will cater for both of these scenarios.
Scenario 1: When the window is maximum size below is the dom:
<tbody>
<tr><td class="sv-table-col-xs"><img src="image.gif">
</td>
<td>03/Mar/2020</td>
<td><span class="sv-label sv-label-primary">You</span>
</td><td>0% of 1</td>
<td>Complete academic review</td>
</tr>
</tbody>
I am using xpath:
//tr[td[contains(text(), '03/Mar/2020')]]//a[text()='Complete academic review']
This works fine and finds the element.
Scenario 2: Below is the DOM when window is shrinked
<tbody>
<tr><td class="sv-table-col-xs">
<b class="tablesaw-cell-label">Status</b>
<span class="tablesaw-cell-content"><img src="../images/emailunr.jpg" style="border:0px" alt="..\images\icons\exploding_email1.gif.gif"></span>
</td>
<td><b class="tablesaw-cell-label">Due Date</b>
<span class="tablesaw-cell-content">03/Mar/2020</span>
</td>
<td><b class="tablesaw-cell-label">Primary Reviewer</b>
<span class="tablesaw-cell-content"><span class="sv-label sv-label-primary">You</span></span>
</td>
<td class="tablesaw-cell-hidden"><b class="tablesaw-cell-label">Other Reviewers</b>
<span class="tablesaw-cell-content">0% of 1</span>
</td>
<td class="tablesaw-cell-hidden"><b class="tablesaw-cell-label">Action</b><span class="tablesaw-cell-content">
Complete academic review
</span></td></tr>
</tbody>
For this the xpath changes to:
//tr/td[5]/span/a
to get to both elements I have tried to use:
//tr/td[5]/span/a | //tr[td[contains(text(), '03/Mar/2020')]]//a[text()='Complete academic review']
this xpath works but I on shrinked window I am not validating the element with text contains ''03/Mar/2020' & 'Complete academic review'.
Not sure if there is a way to validate the texts in both scenarios before selecting the element.
You want to use string value of a node. And function text() doesn't do it.
So instead use . or string() at least for date filtering part.
//tr[td[contains(., '03/Mar/2020')]]//a[text()='Complete academic review']
I have been trying this for a few days and am completely stuck. If anybody could help me out I would be very grateful; Im using VB.NET.
The HTML Code:
<tbody>
<tr>
<td class="chat-attachment-cell"></td>
<td class="chat-input-cell">
<textarea class="chat-message-input"></textarea>
</td>
<td class="chat-send-cell"><a href="#" class="chat-send-button"> alt="Send" width="66" height="66" border="0">
</a>
</td>
</tr>
</tbody>
The text box I need to input into is this bit
<textarea class="chat-message-input"></textarea>
Thankyou in advance for any help provided
You select the element then change the .innertext property with what you want.
There are multiple ways to do it, and I can't give you an example because I don't know what you are using nor the whole html, but for example it could look like this:
WebBrowser1.Document.GetElementById("someid").InnerText="Sometext"
For start, you can try looking how the collection of elements you get looks, then you should be able to figure out what to do next.
Dim test = WebBrowser1.Document.GetElementsByTagName("textarea")
For example on this page:
Dim test = WebBrowser1.Document.GetElementsByTagName("tbody")
test(1).InnerText = "Hi there"
I'm trying to copy text from a website with the following code and I want it to automatically click the "NEXT" button at the end of the table, without clicking it the code works just fine but when I add the last line to click it gives the error:
"Message: Element is no longer attached to the DOM Stacktrace: at
fxdriver.cache.getElementAt
(resource://fxdriver/modules/web-element-cache.js:9354)
at Utils.getElementAt (file:///c:/users/user/appdata/local/temp/tmpa7dvts/extensions/fxdriver#googlecode.com/components/command-processor.js:8978)
at WebElement.getElementText (file:///c:/users/user/appdata/local/temp/tmpa7dvts/extensions/fxdriver#googlecode.com/components/command-processor.js:11965)
at DelayedCommand.prototype.executeInternal_/h (file:///c:/users/user/appdata/local/temp/tmpa7dvts/extensions/fxdriver#googlecode.com/components/command-processor.js:12534)
at DelayedCommand.prototype.executeInternal_ (file:///c:/users/user/appdata/local/temp/tmpa7dvts/extensions/fxdriver#googlecode.com/components/command-processor.js:12539)
at DelayedCommand.prototype.execute/< (file:///c:/users/user/appdata/local/temp/tmpa7dvts/extensions/fxdriver#googlecode.com/components/command-processor.js:12481)"
The code I'm using is:
driver = webdriver.Firefox()
driver.get("https://it.website.com/Statistics")
wait = ui.WebDriverWait(driver, 10)
wait.until(page_is_loaded)
Next_first = 0
Next_first = driver.find_elements_by_id("next")[0]
data_vector [i]=driver.find_elements_by_class_name("tn")[i].text
Next_first.click()
While the website code is:
<tr>
<td class="tn"> text
</td>
<table class="table class" id="table id">
<thead>...code for table title...
</thead>
<tbody>
<tr>
<td class="tn">data
</td>
</tr>
</tbody>
<dd>
<a class="option clickable" id="next" data-page="1">NEXT</a>
</dd>
</tr>
Is there more than the html-source, like javascript?
Because the input could be detached by javascript, which means you have to wait for it to load properly ( driver.implicitly_wait(#seconds) )
here the link to the discription of "implicit-waits"
The second solution could be that you have to clear the cache/cookies of the webdriver before testing, which is described here
I need to perform validation against the table that is being displayed like this.
code sample how I'm trying to find the checkbox Element
//navigate t the second tr where the input and img tags are stored
List<WebElement> daysCheckBox = this.driver.findElements(By.xpath(".//*[#id='RULE_KEY']/div/div/div/div/div/center[1]/table[2]/tbody/tr[2]/td"));
System.out.println("Test checkbox");
for(WebElement td : daysCheckBox){
System.out.println(td.getTagName());
}
The problems I have is that this table come with 2 tags first row represents the days and the second "checkboxes" as you can see they line up with days, however checkbox have no link to each day. I have tried to solve this with reverse logic to try to identify the input tag if it is disabled. But when the box is selected it turns from input tag into img tag, also when I identify input tags I cannot pinpoint what day deselected box it corresponds to.
Does anyone have any advice or suggestion how to approach this type of validation?
Thank you.
I have put the source to make it clearer how the picture above is presented.
<tbody>
<tr bgcolor="whitesmoke">
<td><b>Sun</b></td>
<td><b>Mon</b></td>
<td><b>Tues</b></td>
<td><b>Wed</b></td>
<td><b>Thurs</b></td>
<td><b>Fri</b></td>
<td><b>Sat</b></td>
</tr>
<tr>
<td><img src="webwb/dhtmlx_iconcheckall.gif" /></td>
<td><input disabled="disabled" type="checkbox" /></td>
<td><input disabled="disabled" type="checkbox" /></td>
<td><input disabled="disabled" type="checkbox" /></td>
<td><img src="webwb/dhtmlx_iconcheckall.gif" /></td>
<td><img src="webwb/dhtmlx_iconcheckall.gif" /></td>
<td><input disabled="disabled" type="checkbox" /></td>
</tr>
</tbody>
You can create method which will convert Your table to Java Map for example:
public static Map<String,String> getTableAsMap(WebDriver driver)
{
Map<String,String> checkboxMap = new TreeMap<>();
List<WebElement> header = driver.findElements(By.xpath("((//tbody/tr)[1])/td/*"));
List<WebElement> checkboxes = driver.findElements(By.xpath("((//tbody/tr)[2])/td/*"));
for(int i = 0;i<header.size();i++){
//Only for testing purpose
System.out.printf("KEY: %s, VALUE: %s\n",header.get(i).getText(),checkboxes.get(i).getAttribute("disabled"));
checkboxMap.put(
header.get(i).getText(),
checkboxes.get(i).getAttribute("disabled")
);
}
return checkboxMap;
}
Then In your main class with driver use:
Webdriver driver = new FirefoxDriver();
Map<String,String> map = getTableAsMap(driver);
System.out.println(map.get("Fri"));
System.out.println(map.get("Sat"));
For disabled (non selected) checkbox You will receive true for selected there will be null. Both as String.
as you haven't posted the code, my answer also doesn't have a code :)
Create the WebElement for second row, i.e. xpath: //tbody/tr[2]
Now traverse all the tds inside this row and check their child element.
If the child element is input you know that checkbox is not selected else it is.
About for which day, you know the first is Sunday and Second is Monday and so on..
The Page Object Model approach may be effective to deal with this scenario. So, you can refresh your page object after some action/set of actions.
Since you mentioned that once a checkbox is checked the tag gets changed for the element, so I assume this can happen multiple times in the page based on user activity.
I can suggest that you implement a callback that reloads the and set the page objects on user action say click. With the page objects, you always have track of all the WebElements, accessibility and any change of state.
I want to find the the element for the Edit:
my java code is not working.
String xpathLocater = "//a[contains(text(),'onEditFilter('modifier')')]";
return driver.findElement(By.xpath(xpathLocater));
This is the source code for the element.
<tr class="listeven">
<td>
<a onclick="return onEditFilter('modifier');" href="#">Edit</a>
</td>
</tr>
something like
String xpathLocater = "//a[contains(#onclick,\"onEditFilter('modifier')\")]"