selecting option from hidden drop down menu - selenium

<table id="rusTable" class="groupTable" cellspacing="0" cellpadding="0">
<tbody class="ui-sortable" style="">
<tr class="groupTop ruBorder" style="display: table-row;">
<tr id="ru0" class="siru">
<tr class="ruOp off">
<td class="first"></td>
<td colspan="3">
<select class="ruOpSelect">
<option></option>
<option value="AND">AND</option>
<option>AND NOT</option>
<option>OR</option>
</select>
</td>
<td class="last"></td>
</tr>
<tr id="ru1" class="siru">
<tr class="ruOp off">
<td class="first"></td>
<td colspan="3">
<td class="last"></td>
</tr>
<tr id="ru2" class="siru">
<tr class="groupBtm ruBorder" style="display: table-row;">
</tbody>
<tfoot>
</table>
I want to select the AND option
Selenium webdriver code
actions.moveToElement(driver.findElement(By.xpath("//*#id='ruTable']/tbody/tr[3]/td[2]"))).build().perform();
waitForElement(By.xpath("(//*[#id='ruTable']//*[contains(#class,'ruOpSelect')])[1]"),30);
new Select(driver.findElement(By.xpath("(//*[#id='ruTable']//*[contains(#class,'ruOpSelect')])[1]"))).selectByVisibleText("AND");
It does hover action but does not select anything from drop down menu
ERROR - Timed out after 30 seconds waiting for visibility of element located by By.xpath:
(//*[#id='ruTable']//*[contains(#class,'ruOpSelect')])[1]

Try using this xpath, just call click on this:
"//select[#class='ruOpSelect']/option[text()='AND']"
Any drop downs I generally start with the "select" in my xpath and next level should be option.

I use
Thread.sleep(3000);
after the moveToElement action. Works for me. Then I suppose you need to click the element to select it.

You can use this code to select the particular option
IdentifyBy By;
waitForDropDownEnable(By.xpath, "xpath");
WebElement element = findElement(BY.xpath("xpath for the element"));
Select select = new Select(element);
List<WebElement> options = select.getOptions();
String values = "";
for(int index=0; index<options.size(); index++) {
if(!values.equals("")) {
values += ", ";
}
values += options.get(index).getText();
}
select.selectByVisibleText(value);
public void waitForDropDownEnable(final IdentifyBy idBy, final String controlDesc) {
int timeout =30 * 1000;
final long MAX_TIME_OUT = 300000;
final long DELAY = 250;
final long DEAD_LINE = System.currentTimeMillis() + MAX_TIME_OUT;
boolean isEnabled = false;
try {
while(System.currentTimeMillis() <= DEAD_LINE) {
getWebDriver().manage().timeouts().implicitlyWait(0,TimeUnit.SECONDS);
if(findElement(By.xpath("")).isEnabled()) {
isEnabled = true;
break;
}
Thread.sleep(DELAY);
}
} catch (WebDriverException wdex) {
;;
} catch(Exception ex) {
;;
}
}
}

selecting option from hidden drop down menu
in such case i use jsExecutor. Always works for me:
String cssLocator = "tbody.ui-sortable tr.ruOp off td select.ruOpSelect option[value="AND"]";
//find css locator of the needed AND element in dropdown. I use firepath (addon to firebug).
JavascriptExecutor js = (JavascriptExecutor) driver;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("var x = $(\'"+cssLocator+"\');");
stringBuilder.append("x.click();");
js.executeScript(stringBuilder.toString());
Hope this works for you

Related

Selenium and JavaScript: Accessing multiple elements with the same ID

I've got a page (Angular8) with multiple button/input elements having the same ID.
The ID's are, in the order the appear on the page:
1: for="lastOppDokument-0-VERGE-LEGITIMASJON"
2: for="lastOppDokument-1-VERGE-VERGEMAL"
...
3: for="lastOppDokument-0-VERGE-LEGITIMASJON"
4: for="lastOppDokument-1-VERGE-VERGEMAL"
The elements on lines 1,3 and 2,4 have the same ID.
I'm trying to access the elements using XPath and index like this:
driver.findElement(By.xpath("(//input[#for='lastOppDokument-0-VERGE-LEGITIMASJON'])[1]
driver.findElement(By.xpath("(//input[#for='lastOppDokument-0-VERGE-LEGITIMASJON'])[2]
If I check the size:
int x = driver.findElements(By.xpath("(//input[#for='lastOppDokument-0-VERGE-LEGITIMASJON'])")).size();
it says "2", which is correct.
However, when I try to click those two buttons, the first one (LINE 1) is clicked, but then the next button on the page (LINE 2) i clicked istead of the one on LINE 3.
There's obviously something wrong with my XPath expression, but what? Also, the page is an Angular page, and in the markup code "for" is used to automatically index the ID. But selenium finds the elements (albeit not all the correct ones) using ID. But maybe I need to use something else to identify the correct elements?
UPDATE:
To troubleshoot, I'm skipping the use of a loop and just trying to access the two elements manually:
WebElement buttonToClick = driver.findElement(By.xpath("(//input[#id='lastOppDokument-0-VERGE-LEGITIMASJON'])[1]"));
filUtils.uploadFile(buttonToClick, legitimasjonfil);
WebElement buttonToClick2 = driver.findElement(By.xpath("(//input[#for='lastOppDokument-0-VERGE-LEGITIMASJON'])[2]"));
filUtils.uploadFile(buttonToClick2, legitimasjonfil);
The uploadFile (and related) methods:
public void uploadFile(WebElement id, String filename) {
id.sendKeys(getAbsolutePathToTestFile(TESTFILER_PATH + "/" + filename));
}
private String getAbsolutePathToTestFile(String path) {
return copyFileToTargetTempPath(path, path);
}
private String copyFileToTargetTempPath(String originPath, String destinationPath) {
InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(originPath);
File destination = new File(TARGET_TEMP_PATH + destinationPath);
try {
assert resourceAsStream != null;
org.apache.commons.io.FileUtils.copyInputStreamToFile(resourceAsStream, destination);
} catch (IOException e) {
throw new RuntimeException(e);
}
return destination.getAbsolutePath();
}
UPDATE 2:
<td>
<span class="hb-felt knappesamling-gruppe hb-avstandIngen ng-star-inserted">
<input class="hb-lastOppFil-input hb-bare-skjermleser" type="file" id="lastOppDokument-0-VERGE-LEGITIMASJON"
accept=".pdf,.bmp,.gif,.jpeg,.jpg,.png,.tiff">
<label class="hb-knapp hb-knapp--standard hb-spinner-tekst" for="lastOppDokument-0-VERGE-LEGITIMASJON"> Velg fil </label><!---->
</span>
</td>
<td>
<span class="hb-felt knappesamling-gruppe hb-avstandIngen ng-star-inserted">
<input class="hb-lastOppFil-input hb-bare-skjermleser" type="file" id="lastOppDokument-1-VERGE-VERGEMAL"
accept=".pdf,.bmp,.gif,.jpeg,.jpg,.png,.tiff"><label class="hb-knapp hb-knapp--standard hb-spinner-tekst" for="lastOppDokument-1-VERGE-VERGEMAL"> Velg fil </label><!----></span>
<label class="hb-knapp hb-knapp--standard hb-spinner-tekst" for="lastOppDokument-1-VERGE-VERGEMAL"> Velg fil </label>
</span>

Why Am Getting Unable To Locate Element Error?

I Have Divided The Xpath into 4 Parts Because in Xpath only one Row Value Changes That is /tr[2] Like that 3,4,5 upto the Path Ends.
public class NewTest {
#Test
public void f() throws InterruptedException
{
System.setProperty("webdriver.chrome.driver", "F:\\New folder\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("http://xxxxxxxxxxx/index.aspx");
driver.manage().window().maximize();
WebElement ee= driver.findElement(By.id("ddlstore"));
Select s11 = new Select(ee);
s11.selectByVisibleText("xxxxxx");
String s1 = "/html[1]/body[1]/form[1]/div[5]/center[1]";
String s2 = "/div[1]/table[1]/tbody[1]/tr[";
String s3 ="]";
String s4 = "/td[11]/input[1]";
for(int i=2;i<=99;i++)
{
String finalXpath= s1+s2+i+s3+s4;
driver.findElement(By.xpath(finalXpath)).click();
Thread.sleep(3000);
try {
WebElement e1 = driver.findElement(By
.xpath("//p[#id='skipcount']"));
System.out.println(e1.getText());
WebElement e2 = driver.findElement(By.xpath("/html/body/div[1]/div/div"));
WebElement e3 = driver.findElement(By.xpath("/html/body/div[1]/div/div/div[3]/button[2]"));
Actions a1 = new Actions(driver);
a1.moveToElement(e2).click(e3).build().perform();
} catch (Exception e) {
System.out.println("Can't Click on The Element ");
}
}
The Element is Not Clicking it is Showing an Error , Unable to Locate Element,Xpath
Html Code For The First Xpath Divided into String :
<input type="submit" name="CustomPaging_GridView$ctl02$ff" value="SKIP" onclick="product_skip(this);" id="CustomPaging_GridView_ff_0" class="button2" data-id="12691247570" data-id1="36025">
Html Code For Xpath Which is in Try/Catch Block:
<div class="modal-footer">
<span id="prcid" style="display:none;">processing...</span>
<button type="button" id="skipok" onclick="skipoverall(this)" class="btn btn-primary" data-id="12691247570" data-id1="36025">Ok</button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
</div>
Ps : Actually The Doubt is, I Need To Click an Skip Button Which has an Same Xpath For All Button and Each Time When i Click Skip Button an Popup Will Appear in That i Need To Click The Cancel Button
Try this :
int i = 1;
String s2 = "/div[1]/table[1]/tbody[1]/tr[' " +i+ " '];
There is no need of String s3.
Try this:
// you don't need 'e2', instead you hover 'e3' and click on it
WebElement e3 = driver.findElement(By.xpath("/html/body/div[1]/div/div/div[3]/button[2]"));
Actions a1 = new Actions(driver);
a1.moveToElement(e3).click(e3).build().perform();
Suggestion:
String s1 = "/html[1]/body[1]/form[1]/div[5]/center[1]";
String s2 = "/div[1]/table[1]/tbody[1]/tr[";
String s3 ="]";
String s4 = "/td[11]/input[1]";
for(int i=2;i<=99;i++)
{
String finalXpath= s1+s2+i+s3+s4;
can be replaced with:
for(int i=2;i<=99;i++)
{
String finalXpath= "/html[1]/body[1]/form[1]/div[5]/center[1]/div[1]/table[1]/tbody[1]/tr[" + i + "]/td[11]/input[1]";
...

Custom Selenium Formatter - How do I get comments?

I've been following this tutorial to write a custom selenium formatter: http://seleniumrecipes.com/content/adding-custom-formats.
Comments in a Selenium test script don't follow the general layout
<tr>
<td>pause</td>
<td>6000</td>
<td></td>
</tr>
<!--This is a comment-->
But you still get a command as you loop through the commands in the testCase, but all the values are undefined.
var commands = testCase.commands;
for (var i = 0; i < commands.length; i++) {
var command = commands[i];
result += command.command + ',' + command.target + ',' + command.value + "\n";
}
return result;
I've briefly looked at the source and can't see anything.
Is there a way to get the comments from a Selenium script in a formatter?

font family is not working in PDF

I'm converting HTML to PDF as below:
public const string PdfDocumentHeaderHtml = #"<!DOCTYPE html>
<html lang='en' xmlns='http://www.w3.org/1999/xhtml'>
<head>
<meta charset='utf-16' />
<title></title>
</head>
<body>
<table>
<tr>
<td colspan='3'>
<span Style='font-family:Arial;font-size:10pt;font-weight:bold;'>{0}</span>
<br/>
<br/>
<span class='pageHeaderText'>{1}</span>
</td>
<td colspan='1'>
<span><img src='' width='150' height='90' alt='NOS'/></span>
</td>
</tr>
</table>
</body>
</html>";
And save to PDF using the below code:
public override void OnCreatePDF(PdfWriter writer, Document document)
{
iTextSharp.text.FontFactory.Register(#"C:\Windows\Fonts\arial.ttf", "Arial");
base.OnCreatePDF(writer, document);
if (writer == null)
throw new ArgumentNullException("writer");
if (document == null)
throw new ArgumentNullException("document");
var headerHtml = string.Format(Constants.NosPdfDocumentHeaderHtml, Urn, Title);
var providers = new Dictionary<string, Object> { { HTMLWorker.IMG_BASEURL, string.Format(Constants.HeaderImageLocation, SiteUrlForHeaderImage) } };
List<IElement> htmlarraylist = HTMLWorker.ParseToList(new StringReader(headerHtml), null, providers);
foreach (IElement htmlElement in htmlarraylist)
{
document.Add(htmlElement);
document.Add(new LineSeparator((float)0.90, 100, new BaseColor(0, 112, 192, 0), 0, 0));
}
}
I want to set Font-Family:Arial for the PDF but the problem is, when I see the PDF-File properties, it says Helvetica is used.
I think I need to download Adobe Font Metric file (arial.afm file) and set this font family (instead of arial.ttf) for use with pdf. But I don't know how to do it.
Could you please advice?
Thanks,
In the comment section, you are asking for an alternative to add a table structure to a document.
That's easy with PdfPTable. For instance, if I want to create a table with 3 columns, I do:
PdfPTable table = new PdfPTable(3);
I want to span 100% of the available width between the margins of the page, so I do:
table.WidthPercentage = 100;
I want the first column to be twice as wide as column two and three, so I do:
table.SetWidths(new int[]{2, 1, 1});
Now I add cells:
PdfPCell cell;
cell = new PdfPCell(new Phrase("Table 1"));
cell.Colspan = 3;
table.AddCell(cell);
cell = new PdfPCell(new Phrase("Cell with rowspan 2"));
cell.Rowspan = 2;
table.AddCell(cell);
table.AddCell("row 1; cell 1");
table.AddCell("row 1; cell 2");
table.AddCell("row 2; cell 1");
table.AddCell("row 2; cell 2");
Finally, I add the table to the Document:
document.Add(table);
And that's it.

Selenium tbody text extraction

The web application I am trying to automate has a diagnostic tool that allows to ping to a website. It provides output in a box that has a table structure (all of it is included i na ).
I am automating it using Selenium WebDriver and Java to program one. It is structured as a JUnit 4 test and uses WebDriver (not Selenium RC, but the newer one)
Here is what it looks like:
<tr>
<td style="font-family:Arial;font-size:11px;"></td>
</tr>
<tr>
<td style="font-family:Arial;font-size:11px;"> </td>
</tr>
<tr>
<td style="font-family:Arial;font-size:11px;">PING ds-any-fp3-real.wa1.b.yahoo.com (98.138.253.109) 56(84) bytes of data.</td>
</tr>
<tr>
<td style="font-family:Arial;font-size:11px;">64 bytes from ir1.fp.vip.ne1.yahoo.com (98.138.253.109): icmp_req=1 ttl=53 time=81.9 ms</td>
</tr>
<tr>
<td style="font-family:Arial;font-size:11px;">64 bytes from ir1.fp.vip.ne1.yahoo.com (98.138.253.109): icmp_req=2 ttl=53 time=148 ms</td>
</tr>
<tr>
<td style="font-family:Arial;font-size:11px;">64 bytes from ir1.fp.vip.ne1.yahoo.com (98.138.253.109): icmp_req=4 ttl=53 time=143 ms</td>
</tr>
<tr>
<td style="font-family:Arial;font-size:11px;"></td>
</tr>
<tr>
<td style="font-family:Arial;font-size:11px;">--- ds-any-fp3-real.wa1.b.yahoo.com ping statistics ---</td>
</tr>
<tr>
<td style="font-family:Arial;font-size:11px;">5 packets transmitted, 3 received, 40% packet loss, time 4012ms</td>
</tr>
<tr>
<td style="font-family:Arial;font-size:11px;">rtt min/avg/max/mdev = 81.917/124.763/148.373/30.349 ms</td>
</tr>
<tr>
<td style="font-family:Arial;font-size:11px;"></td>
</tr>
</tbody>
And here is what it looks like on the page:
PING ds-any-fp3-real.wa1.b.yahoo.com (98.138.253.109) 56(84) bytes of data.
64 bytes from ir1.fp.vip.ne1.yahoo.com (98.138.253.109): icmp_req=1 ttl=53 time=81.9 ms
64 bytes from ir1.fp.vip.ne1.yahoo.com (98.138.253.109): icmp_req=2 ttl=53 time=148 ms
64 bytes from ir1.fp.vip.ne1.yahoo.com (98.138.253.109): icmp_req=4 ttl=53 time=143 ms
--- ds-any-fp3-real.wa1.b.yahoo.com ping statistics ---
5 packets transmitted, 3 received, 40% packet loss, time 4012ms
rtt min/avg/max/mdev = 81.917/124.763/148.373/30.349 ms
I need to parse this text using Selenium WebDriver and pass the JUnit test if the ping was successful (doesn't matter if the packets have been lost), I need to extract an IP address as well.
Is there any way I can extract the particular part of the page source (maybe, using driver.getPageSource() in some sophisticated way or finding this piece by xpath and then calling getText()?) and then parse it to get IP out? The way I tried it is as folows:
String IP = "";
String textToParse = //Here, we should have a way to get the string that would contain IP.
String tokenSeparators = "()"; // since our IP is enclosed by brackets
String tokens[] = textToParse.split(tokenSeparators);
for(int i = 0; i<tokens.length; i++){
if(tokens[i].matches("^[1-9]?[1-9]?[1-9]?\\.[1-9]?[1-9]?[1-9]?\\.[1-9]?[1-9]?[1-9]?\\.[1-9]?[1-9]?[1-9]?$")){ // IP regexp
IP = tokens[i]
}
}
Let me know how to extract the text that I need to parse and whether there are errors in my code (for example, if my regexp is right)
Will appreciate any help!
List<WebElement> allTds=driver.findElements(By.cssSelector("td[style*='font-family:Arial;font-size:11px;']");
String allTdText[]=new String[allTds.size()];
int i=0;
for(WebElement eachTd:allTds)
{
allTdText[i++]=eachTd.getText();
}
By using above logic you will get all td tags data in String array. after that parse each individual arraye element as your requirement.
Example :
String a="64 bytes from ir1.fp.vip.ne1.yahoo.com (98.138.253.109): icmp_req=1 ttl=53 time=81.9 ms";
For getting IP address alone
System.out.println(a.substring(a.indexOf("(")+1,a.indexOf(")")));
it will return 98.138.253.109