HtmlUnit accessing an element without id or Name - java

How can I access this element:
<input type="submit" value="Save as XML" onclick="some code goes here">
More info: I have to access programmatically a web page and simulate clicking on a button on it, which then will generate a xml file which I hope to be able to save on the local machine.
I am trying to do so by using HtmlUnit libraries, but all examples I could find use getElementById() or getElementByName() methods. Unfortunately, this exact element doesn't have a name or Id, so I failed miserably. I supposed then that the thing I have to do is use the getByXPath() method but I got completely lost into XPath documentation(this matter is all new to me).
I have been stuck on this for a couple of hours so I really need all the help I can get.
Thanks in advance.

There are several options for an XPATH to select that input element.
Below is one option, which looks throughout the document for an input element that has an attribute named type with the value "submit" and an attribute named value with the value "Save as XML".
//input[#type='submit' and #value='Save as XML']
If you could provide a little bit more structure, a more specific (and efficient) XPATH could be created. For instance, something like this might work:
/html/body//form//input[#type='submit' and #value='Save as XML']
You should be able to use the XPATH with code like this:
client = new WebClient(BrowserVersion.FIREFOX_3)
client.javaScriptEnabled = false
page = client.getPage(url)
submitButton = page.getByXPath("/html/body//form//input[#type='submit' and #value='Save as XML']")

Although I would, in most cases, recommend using XPath, if you don't know anything about it you can try the getInputByValue(String value) method. This is an example based on your question:
// Fetch the form somehow
HtmlForm form = this.page.getForms().get(0);
// Get the input by its value
System.out.println(form.getInputByValue("Save as XML").asXml());

Related

Unable to get the text from div class - selenium java

<div class="jss7113 jss7118"><div></div><div class="jss7114">Invalid username or password</div><button class="MuiButtonBase-root MuiButton-root MuiButton-text MuiButton-textPrimary" tabindex="0" type="button"><span class="MuiButton-label"><i icon="close-circle-outline" title="" class="mdi mdi-close-circle-outline" aria-hidden="true"></i></span><span class="MuiTouchRipple-root"></span></button></div>
This is what wrote
//System.out.println(driver.findElement(By.cssSelector("*.jss5107")).getText()); //Get the error message from the Invalid credentials
//System.out.println(driver.findElement(By.cssSelector("div[class = 'jss7114']")).getText().equals("Invalid username or password"));
//System.out.println(driver.findElement(By.xpath("//div[#class = 'jss7114']")).getText().equals("Invalid username or password"));
It seems like the class name you're trying to find doesn't exist:
//System.out.println(driver.findElement(By.cssSelector("*.jss5107")).getText());
this type of gibberish names for elements usually indicates random attribute values being generated and making your automation relying on those values is a no go because we want our automation to be as solid and low maintenance as possible.
Instead, try to find a better way to locate the element you're looking for.
I could've tried to give you a better locator but it seems like you pasted a part of the HTML code which I can't read it properly (for example there's a div tag that immediately gets closed right after):
<div class="jss7113 jss7118"><div></div>
Please provide a better snippet of this part of the HTML in order for us to help with your question.
If you want to validate the message, you can locate the element by the text within it:
driver.findElement(By.xpath("//div[contains(text(),'Invalid username or password')]

How to locate dynamic downloaded filename using Selenium + Java

I am not able to locate the chrome downloaded filename using locator. I need to get the filename to proceed further on automation to verify the content.
Element HTML:
<a is="action-link" id="file-link" focus-row-control="" focus-type="fileLink" tabindex="0" role="link" href="https://energyfuture.cgi.com/pasdemo/operations/QueryDisplay!displayQuery.action?QUERY_TIMESTAMP=1614571607262" class="">Facility Balance_1614571607828.xlsx</a>
Here the numbers of filename are dynamic, but the prefix Facility Balance will be constant.
code I have tried:
driver.navigate().to("chrome://downloads/");
String Text = driver.findElement(By.xpath("//*[#id='file-link']")).getText();
OR
String AttributeData = driver.findElement(By.xpath("//*[contains(text(),'Facility Balance')]")).getAttribute("linkText");
For starters
.getAttribute("linkText");
will not work because your target node does not contain an attribute called linkText.
The second point,
By.xpath("//*[#id='file-link']")
might not work if you have multiple elements with the same ID on the page (this include popups). Consider refining your xpath to be more explicit. For example, By.xpath("//a[#id='file-link' and ...]") where the ... are additional conditions that will refine your search to find only one.
Out of curiosity, did you try your Xpath directly in the browser developer's tools? Before you attempt to code things like this, you should always attempt to evaluate your XPath expressions to make sure that 1) they are accurate and 2) they are not ambiguous. Unfortunately, given the amount of information posted, this is the extent of the help I can give you.

How to find element having dynamic ID / Name changing on every page load using Selenium WebDriver

I found a few answers about this but they did not answer my question an so I am writing a new question.
I have HTML code having below kind of checkbox elements (in browser's inspect element)
<input role="checkbox" type="checkbox" id="jqg_TransactionFormModel501EditCollection2_147354_grid_-1274" class="cbox" name="jqg_TransactionFormModel501EditCollection2_147354_grid_-1274" value="true">
In my test case I want to click on checkbox using its ID using Selenium Webdriver.
here Id= "jqg_TransactionFormModel501EditCollection2_147354grid-1274" is dynamic.
in above id, Bold & Italic marked letters (dynamic) will change with different check boxes in same page as well as page refresh.
Bold marked letters (dynamic) will change on page refresh only (remain same through all the check boxes in same page.)
How shoud I format/write XPATH so that I can click on desired check boxes using below statement.
WebElement checkbox = webDriver.findElement(By.id("idOfTheElement"));
if (!checkbox.isSelected()) {
checkbox.click();
}
Thanks for your help in advance.. !
Here are a few examples of xpaths which you can use to find your checkbox
//input[contains(#id,'jqg_TransactionFormModel')]
OR, if you want more checks, try something like
//*[starts-with(#id,'jqg_TransactionFormModel') and contains(#id,'EditCollection2_')]
Additionally, you can try regex as well using matches
//*[matches(#id,'<regex matching your id>')]
You can use partial ID using cssSelector or xpath
webDriver.findElement(By.cssSelector("[id*='TransactionFormModel']"));
webDriver.findElement(By.xpath("//input[contains(#id, 'TransactionFormModel')]"));
You can replace TransactionFormModel with any other fixed part of the ID.
As a side note, no need to locate the element twice. You can do
WebElement checkbox = webDriver.findElement(By.id("idOfTheElement"));
if (!checkbox.isSelected()) {
checkbox.click();
}
You can write xpath like this :
//input[starts-with(#id,'jqg_TransactionFormModel')]
//input[contains(#id,'jqg_TransactionFormModel')]
I recommend not using ID's or xpath and adding a data attribute to your elements. This way, you can avoid the annoyance of xpath and have a strong selector that you feel confident will always be selectable.
For example, you could call the attribute: data-selector. You can assign a value of "transactionFormModelCheckbox". Then, when creating a new element, you create by css selector with the value referenced above.
No matter what type of formatting, you'll always be able to select that checkbox - as long as the element exists in the DOM. If you need to investigate other attributes, you can use the selector to do things like hasClass() or anything else you need.
Hope that helps !

Receive data from html tag with Java in Selenium

I have the following html tag and I want to receive "name":"test_1476979972086" from my Java Selenium code.
How can I achive this?
I already tried getText and getAttribute function but without any success.
<a data-ng-href="#/devices"
target="_blank"
class="ng-binding"
href="#/devices">
{"name":"test_1476979972086"}
</a>
getText() is always emtpy. The xpath is unique. newDevice.created is unique on page.
final By successMessageBy = By.xpath("//p[#data-ng-show='newDevice.created']/a");
final WebElement successMessage = wait.until(ExpectedConditions.presenceOfElementLocated(successMessageBy));
final String msg = successMessage.getText();
Actually WebElement#getText() returns only visible text. It could be possible element is present there but text would be visible later.
So if WebElement#getText() doesn't work as expected, you should try using getAttribute("textContent") as below:-
successMessage.getAttribute("textContent");
upon first glance, the below should work. the fact that what you've tried doesnt work, leads me to believe that you aren't selecting the correct element. since i am ignorant of the rest of your html, this might not be unique. you'll have to play around with it, or share the surrounding html
String json = driver.findElement(By.cssSelector("a[href$='/devices']")).getText()

selenium web driver : Unable to locate element

Well not to mention that I'm new on using the selenium web driver, I'm trying to automatize a mailbox so I can log myself in and to send a message, the thing is that I download the firebug plugin for Mozilla, that is the browser I'm currently working with, when I'm trying to find the element for the log in and the password everything goes well, because I do it by their name.
input class="_nb-input-controller" type="text" **name="login"** autocorrect="off" autocapitalize="off" value=""
input class="_nb-input-controller" type="password" **name="passwd"** value=""
but as soon as im at the mailbox entry the identificator changes it, i go to compose link and this is the code that shows up:
a class="b-toolbar__item b-toolbar__item_compose js-toolbar-item-compose daria-action" title="Compose (w, c)" href="#compose" data-action="compose.go" data-params="toolbar=1&toolbar.button=compose"
Since I don't find any method that could help on this, a friend came and told me about the xpath which was:
/html/body/div[2]/div/div[5]/div/div[3]/div/div[2]/div/div/div/div[2]/a[2]
by doing this selenium did find the element and I could click on the icon,
but again.. when I'm trying to get into the "TO" prompt so I can write inside
it is not finding the element, not by xpath, or anything is there a way or formula to get elements or translate them into a way that selenium can find them???
oh i see, i re try with the element and i noticed that the one i wanted was showing as hidden using firebug so i just try the next one up and the web driver could locate the item, it was a simple app to send an email the prompt that i wanted to locate was the 'TO' field. and thanks guys for giving me the correct way of using the Xpath property
Having locators such as :
/html/body/div[2]/div/div[5]/div/div[3]/div/div[2]/div/div/div/div[2]/a[2]
is generally a bad idea. If you want to build a stable test I would suggest you stay away from such.
Now I see you have attributes like #name and #class. XPath is provides you with a way to reach these elements directly by pointing the identifiers instead of the whole path to the element.
You can try something like:
//input[#name='login']
//input[#name='password']
More info at: http://www.w3schools.com/xsl/xpath_intro.asp

Categories

Resources