Extracting Variable from Javascript Source Using Selenium WebDriver - java

I am working with a page source that runs Javascript to print text on the page. Here is a snippet of the source I'm speaking of:
var display_session = get_cookie("LastMRH_Session");
if(null != display_session) {
document.getElementById("sessionDIV").innerHTML = '<BR>The session reference number: ' + display_session + '<BR><BR>';
document.getElementById("sessionDIV").style.visibility = "visible";
}
The page is displaying the value of the display session variable when it's not null but I want to know if there is a way I can utilize this variable in my Selenium WebDriver code. The function that uses this code in the Javascript does not return the display_session variable and I cannot alter the page source. I tried this based on the post here but it throws an exception.
JavascriptExecutor js = (JavascriptExecutor) driverRp;
Object result = js.executeScript("return display_session");
System.out.println("sessionId = "+result);
Any suggestions?

Figured it out. Needed to go after the cookie itself instead of messing with the Javascript variable.
Cookie cookie = driverRp.manage().getCookieNamed("LastMRH_Session");
String sessionId = cookie.getValue().toUpperCase();
System.out.println("sessionId = "+sessionId);
Found the solution at this post.

If the display_session variable is inside a function the you will not be able to access it unless it is at global scope.
If your intention is to read the value of a cookie, you can use the driver.manage().getCookieNamed(...) as an alternative to executing Javascript.
EDIT:
Just saw that you were able to figure out the same. Didn't see your answer when I posted. Glad it worked out.

Try this:
js.executeScript('return get_cookie("LastMRH_Session")')

Related

Why is my java test script for selenium not printing out a simple confirmation string?

I am trying to finish a test script written in Java. Everything works great and I am trying to print out a confirmation if all previous steps runs which says that account creation was successful.
To do this, I have put the element in a string and then print out the element using the System.out.println command. But for some reason , all I am getting is the following
CONFIRMATION:
That's it. It's supposed to show the string text which reads " Customer information added successfully" . I been trying for the past 2 hours to get it to print it. Can someone please help ?
Here's my code that's causing the problem.
String conf = driver.findElement(By.id("MainContent_lblTransactionResult")).getText();
System.out.println("CONFIRMATION: " + conf);
I have checked and rechecked the element id and it is the correct element id.
https://imgur.com/RUPN3Ea ( Confirmation page )
https://imgur.com/c2YtIAD ( Eclipse output )
Try this
String conf = driver.findElement(By.id("MainContent_lblTransactionResult")).innerHTML;
What you are trying to pull out of the element is in the innerHTML
Use some delay like Webdriver wait.until or Thread sleep after hitting the submit. Try to get text using JavascriptExecutor like below:
JavascriptExecutor jse = (JavascriptExecutor)driver;
String conf = jse.executeScript("$('#MainContent_lblTransactionResult').text();", "");
System.out.println("CONFIRMATION: " + conf);
You can also try using .html() instead of .text()
String conf = jse.executeScript("$('#MainContent_lblTransactionResult').html();", "");
Hopefully it resolves your issue.

element not interactable exception in selenium web automation

In the below code i cannot send password keys in the password field, i tried clicking the field, clearing the field and sending the keys. But now working in any of the method. But its working if i debug and test
public class TestMail {
protected static WebDriver driver;
protected static String result;
#BeforeClass
public static void setup() {
System.setProperty("webdriver.gecko.driver","D:\\geckodriver.exe");
driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
}
#Test
void Testcase1() {
driver.get("http://mail.google.com");
WebElement loginfield = driver.findElement(By.name("Email"));
if(loginfield.isDisplayed()){
loginfield.sendKeys("ragesh#gmail.in");
}
else{
WebElement newloginfield = driver.findElemnt(By.cssSelector("#identifierId"));
newloginfield.sendKeys("ragesh#gmail.in");
// System.out.println("This is new login");
}
driver.findElement(By.name("signIn")).click();
// driver.findElement(By.cssSelector(".RveJvd")).click();
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
// WebElement pwd = driver.findElement(By.name("Passwd"));
WebElement pwd = driver.findElement(By.cssSelector("#Passwd"));
pwd.click();
pwd.clear();
// pwd.sendKeys("123");
if(pwd.isEnabled()){
pwd.sendKeys("123");
}
else{
System.out.println("Not Enabled");
}
Try setting an implicit wait of maybe 10 seconds.
gmail.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
Or set an explicit wait. An explicit waits is code you define to wait for a certain condition to occur before proceeding further in the code. In your case, it is the visibility of the password input field. (Thanks to ainlolcat's comment)
WebDriver gmail= new ChromeDriver();
gmail.get("https://www.gmail.co.in");
gmail.findElement(By.id("Email")).sendKeys("abcd");
gmail.findElement(By.id("next")).click();
WebDriverWait wait = new WebDriverWait(gmail, 10);
WebElement element = wait.until(
ExpectedConditions.visibilityOfElementLocated(By.id("Passwd")));
gmail.findElement(By.id("Passwd")).sendKeys("xyz");
Explanation: The reason selenium can't find the element is because the id of the password input field is initially Passwd-hidden. After you click on the "Next" button, Google first verifies the email address entered and then shows the password input field (by changing the id from Passwd-hidden to Passwd). So, when the password field is still hidden (i.e. Google is still verifying the email id), your webdriver starts searching for the password input field with id Passwd which is still hidden. And hence, an exception is thrown.
"element not interactable" error can mean two things :
a. Element has not properly rendered:
Solution for this is just to use implicit /explicit wait
Implicit wait :
driver.manage().timeouts().implicitlyWait(50, TimeUnit.SECONDS);
Explicit wait :
WebDriverWait wait=new WebDriverWait(driver, 20);
element1 = wait.until(ExpectedConditions.elementToBeClickable(By.className("fa-stack-1x")));
b. Element has rendered but it is not in the visible part of the screen:
Solution is just to scroll till the element. Based on the version of Selenium it can be handled in different ways but I will provide a solution that works in all versions :
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].scrollIntoView(true);", element1);
Suppose all this fails then another way is to again make use of Javascript executor as following :
executor.executeScript("arguments[0].click();", element1);
If you still can't click , then it could again mean two things :
1. Iframe
Check the DOM to see if the element you are inspecting lives in any frame. If that is true then you would need to switch to this frame before attempting any operation.
driver.switchTo().frame("a077aa5e"); //switching the frame by ID
System.out.println("********We are switching to the iframe*******");
driver.findElement(By.xpath("html/body/a/img")).click();
2. New tab
If a new tab has opened up and the element exists on it then you again need to code something like below to switch to it before attempting operation.
String parent = driver.getWindowHandle();
driver.findElement(By.partialLinkText("Continue")).click();
Set<String> s = driver.getWindowHandles();
// Now iterate using Iterator
Iterator<String> I1 = s.iterator();
while (I1.hasNext()) {
String child_window = I1.next();
if (!parent.equals(child_window)) {
driver.switchTo().window(child_window);
element1.click()
}
Please try selecting the password field like this.
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement passwordElement = wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#Passwd")));
passwordElement.click();
passwordElement.clear();
passwordElement.sendKeys("123");
you may also try full xpath, I had a similar issue where I had to click on an element which has a property javascript onclick function. the full xpath method worked and no interactable exception was thrown.
In my case the element that generated the Exception was a button belonging to a form. I replaced
WebElement btnLogin = driver.findElement(By.cssSelector("button"));
btnLogin.click();
with
btnLogin.submit();
My environment was chromedriver windows 10
In my case, I'm using python-selenium.
I have two instructions. The second instruction wasn't able to execute.
I put a time.sleep(1) between two instructions and I'm done.
If you want you can change the sleep amount according to your need.
I had the same problem and then figured out the cause. I was trying to type in a span tag instead of an input tag. My XPath was written with a span tag, which was a wrong thing to do. I reviewed the Html for the element and found the problem. All I then did was to find the input tag which happens to be a child element. You can only type in an input field if your XPath is created with an input tagname
I'm going to hedge this answer with this: I know it's crap.. and there's got to be a better way. (See above answers) But I tried all the suggestions here and still got nill. Ended up chasing errors, ripping the code to bits. Then I tried this:
import keyboard
keyboard.press_and_release('tab')
keyboard.press_and_release('tab')
keyboard.press_and_release('tab') #repeat as needed
keyboard.press_and_release('space')
It's pretty insufferable and you've got to make sure that you don't lose focus otherwise you'll just be tabbing and spacing on the wrong thing.
My assumption on why the other methods didn't work for me is that I'm trying to click on something the developers didn't want a bot clicking on. So I'm not clicking on it!
I got this error because I was using a wrong CSS selector with the Selenium WebDriver Node.js function By.css().
You can check if your selector is correct by using it in the web console of your web browser (Ctrl+Shift+K shortcut), with the JavaScript function document.querySelectorAll().
If it's working in the debug, then wait must be the proper solution.
I will suggest to use the explicit wait, as given below:
WebDriverWait wait = new WebDriverWait(new ChromeDriver(), 5);
wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#Passwd")));
I came across this error too. I thought it might have been because the field was not visible. I tried the scroll solution above and although the field became visible in the controlled browser session I still got the exception. The solution I am committing looks similar to below. It looks like the event can bubble to the contained input field and the end result is the Selected property becomes true.
The field appears in my page something like this.
<label>
<input name="generic" type="checkbox" ... >
<label>
The generic working code looks more or less like this:
var checkbox = driver.FindElement(By.Name("generic"), mustBeVisible: false);
checkbox.Selected.Should().BeFalse();
var label = checkbox.FindElement(By.XPath(".."));
label.Click();
checkbox.Selected.Should().BeTrue();
You'll need to translate this to your specific language. I'm using C# and FluentAssertions. This solution worked for me with Chrome 94 and Selenium 3.141.0.
I had to hover over the element first for the sub-elements to appear. I didn't take that into account at first.
WebElement boardMenu = this.driver.findElement(By.linkText(boardTitle));
Actions action = new Actions(this.driver);
action.moveToElement(boardMenu).perform();
Another tip is to check that you are having one element of that DOM. Try using Ctrl+F when inspecting the web page and check your xpath there; it should return one element if you are going with the findElement method.

Java. HtmlUnitDriver. Drop down Window issue

I'm using HtmlUnit in Java to deal with a DropDown Window (Java).
I tried as User skaffman suggests:
WebDriver driver = new HtmlUnitDriver();
driver.get("https://...");
......................
WebClient client = new Webclient();
Page page = client.getPage("https://...");
HtmlSelect select = (HtmlSelect) page.getElementById(mySelectId);
HtmlOption option = select.getOptionByValue(desiredOptionValue);
select.setSelectedAttribute(option, true);
It does not recognize: getElementById. Eclipse recommends to swith to findElement(By.id(" ")) PLEASE HELP
I agree with my college. The above code is correct, make sure you set javascript enabled, otherwise you will have issues with HtmlUnit
driver = new HtmlUnitDriver();
((HtmlUnitDriver) driver).setJavascriptEnabled(true);
In your code, you are declaring the local variable to be of the type Page that will contain the return value from client.getPage("https://...");
Although it's usually good practice to develop toward the generic interface (in this case, Page), the generic interface does not contain the method to getElementById(...).
Try changing your 4th line of code to the following:
HtmlPage page = client.getPage("https://...");
(I am assuming that the conent being returned by client.getPage("https://..."); is of MimeType text/html).
You could also use XmlPage or XhtmlPage, depending on your MimeType.
If it is none of these that you are retrieving via client.getPage("https://...");, then you should not be attempting to call getElementById on a structure that does not have this as part of its API.

Manipulate JavaScript using Java

I'm connecting to a webserver with a specific JavaScript. (Using HttpURLConnection atm)
What i need is a connection that makes it possible to manipulate a JavaScript function.
Afterwards i want to run the whole JavaScript again.
I want the following function always to return "new FlashSocketBackend()"
function createBackend() {
if (flashSocketsWork) {
return new FlashSocketBackend()
} else {
return new COMETBackend()
}
}
Do i have to use HtmlUnit for this?
Whats the easiest way to connect, manipulate and re-run the script?
Thanks.
With HtmlUnit you indeed can do it.
Even though you can not manipulate an existing JS function, you can however execute what JavaScript code you wish on an existing page.
Example:
WebClient htmlunit = new WebClient();
HtmlPage page = htmlunit.getPage("http://www.google.com");
page = page.executeJavaScript("<JS code here>").getNewPage();
//manipulate the JS code and re-excute
page = page.executeJavaScript("<manipulated JS code here>").getNewPage();
//manipulate the JS code and re-excute
page = page.executeJavaScript("<manipulated JS code here>").getNewPage();
more:
http://www.aviyehuda.com/2011/05/htmlunit-a-quick-introduction/
Your best shot is probably to use Rhino — an open-source implementation of JavaScript written entirely in Java. Loading your page with a window.location and hopefully running your JavaScript function. I read sometime before Bringing the Browser to the Server and seemed possible.

Can you capture end user's Java version when they run an applet?

An applet developed outside our company just started failing for some users this week. Apparently it was because of the latest version of java (1.6u24) that auto updated. Is there a way to capture what version of java the user opened the applet with?
You can use System.getProperty("java.version") to get that information. This is an example applet that uses it and the About page has the source.
You can use System.getProperty, specifically :
System.getProperty("java.version")
For a list of possible key value, see : getProperties()
http://pscode.org/prop/?prop=java.version%2Cjava.vm.version
Using the answers from another question, I ended up writing the code below. When the page loads, I get the user's java version then use an ajax call to save it where ever I need to. The part I used was the reference to the deployJava.js from Sun.
$(document).ready(function() {
var jVersion = "";
for (var i = 0; i < deployJava.getJREs().length; ++i) {
jVersion += deployJava.getJREs()[i];
}
var url = 'saveJavaVersionAction.jsp';
var params = 'version=' + jVersion;
$.ajax({
url: url,
data: params,
success: function(html) {
$("#results").append(html);
}
});
});

Categories

Resources