How to use following JS code line with java selenium webdriver? - java

Description:
I am using following JS code line using chrome console (whose image is also attached) and the this code gives ids of opened Tabs in a page of my web application (tabs image is also attached to understand output). But Now I don't know how to use this JS code line in my automation script that I am writing using Selenium Web-driver in Java.
Code:
Array.from(document.querySelectorAll("[class*='x-tab x-unselectable x-tab-after-title x-box-item x-tab-default x-top x-tab-top x-tab-default-top x-closable x-tab-closable x-tab-default-closable x-closable-top x-tab-closable-top x-tab-default-closable-top x-icon-text-left x-tab-icon-text-left x-tab-default-icon-text-left']")).map(function(item){return item.id;})
Tabs screen-shot
Question:
Can anybody tell me how to use this code line in selenium Webdriver script using Java?
I am using above JS code line on chrome console opened for my application and it is giving correct result.
Output of above code line using chrome console

I think you can use executeScript method like this:
((JavascriptExecutor) driver).executeScript("arguments[0].click();", element); //click the WebElement via Javascript.
In your case, your code would look like this:
((JavascriptExecutor) driver).executeScript("return Array.from(document.querySelectorAll(\"[class*='x-tab x-unselectable x-tab-after-title x-box-item x-tab-default x-top x-tab-top x-tab-default-top x-closable x-tab-closable x-tab-default-closable x-closable-top x-tab-closable-top x-tab-default-closable-top x-icon-text-left x-tab-icon-text-left x-tab-default-icon-text-left']\")).map(function(item){return item.id;})");
executeScript returns an instance of Object, so in order to work with it, you would have to save the array in a variable and make a cast to ArrayList. You have to add return inside your javascript to tell WebDriver that this method will return something.
Try the following:
List<String> listOfIds = (List<String) ((JavascriptExecutor) driver).executeScript("return Array.from(document.querySelectorAll(\"[class*='x-tab x-unselectable x-tab-after-title x-box-item x-tab-default x-top x-tab-top x-tab-default-top x-closable x-tab-closable x-tab-default-closable x-closable-top x-tab-closable-top x-tab-default-closable-top x-icon-text-left x-tab-icon-text-left x-tab-default-icon-text-left']\")).map(function(item){return item.id;})");
I will show you a warning Type safety: Unchecked cast from Object to List<String> and I don't know how to provide a checked cast. However, this should work.

Related

Extract pagetype value in datalayer using Selenium IDE or Java

I'm trying to extract the value of pageType in dataLayer with Selenium Java but I received a null value in the variable using this line of code:
Object X1 = ((JavascriptExecutor) driver).executeScript("dataLayer[0]['pageType']");
So is there a way to extract that value and put it into a variable or extract it in a simplier way on Selenium IDE?
Edit: I'm running some test on newhomesource.com
Oh, I think I know what the problem is--your script is not returning anything. Try just adding a return,
Object X1 = ((JavascriptExecutor) driver).executeScript("return dataLayer[0]['pageType']");

How to Add a <script> into Head Using Selenium's JavascriptExecutor

Summary
I want to figure out a way to add a <script> tag into the head of DOM using Selenium's JavascriptExecutor, or any other way of doing this would be nice.
I have tried many ways and also found a few similar topics and none of them solved my problem which is why I felt the need to ask it on here.
For example :
Suggested solutions in this question did not solve my problem. Some people say it worked for them but nope, it didn't for me.
What I've been trying to execute?
Here is the small snippet of the code that I want to execute:
WebDriver driver = new FirefoxDriver();
JavascriptExecutor jse = (JavascriptExecutor) driver;
jse.executeScript("var s = document.createElement('script');");
jse.executeScript("s.type = 'text/javascript';");
jse.executeScript("s.text = 'function foo() {console.log('foo')}';");
jse.executeScript("window.document.head.appendChild(s);");
I just skipped the code above where you navigate to a webpage using driver.get() etc. and then try to execute the scripts.
Also, s.text would contain the actual script that I want to use so I just put there a foo() function just to give the idea.
The above code throws this error when you run it:
Exception in thread "main" org.openqa.selenium.JavascriptException: ReferenceError: s is not defined
So far I've tried every possible solution I could find on the Internet but none of them seems to work.
OP came up with the following solution:
jse.executeScript("var s=window.document.createElement('script');" +
"s.type = 'text/javascript';" + "s.text = function foo() {console.log('foo')};" +
"window.document.head.appendChild(s);");
For one, this line is invalid.
jse.executeScript("s.text = 'function foo() {console.log('foo')}';");
Note how you wrap single-quote text in single quotes. Use one set as "\""
I would personally do this by doing (edited to make it a global function):
using OpenQA.Selenium.Support.Extensions;
driver.ExecuteJavascript("window.foo = function foo() {console.log('foo')}");
It's as simple as that. You are registering foo as a method by doing this. After you execute this javascript, you can manually go in to the browser developer tools and call "foo()" to check. Additionally, you can check this by registering it directly in the console. Just enter "function foo() {console.log('foo')}" into your browser console, and then call "foo()".
No need to add this as a script tag.
EDIT #2: I fixed my above code suggestion so that the method is assigned to the window, and thus accessible globally, and outside of the anonymous script that javascript executor runs the code in. The original issues with this not working are resolved by this, at least in my testing of it.

What is the correct way to pass arguments to the JavascriptExecutor?

I'm trying to use the JavascriptExecutor for my code, which involved passing in a WebElement and get some info from it. I was getting some errors, so I simplified it down to find the problem.
String test = ((JavascriptExecutor)driver).executeScript("return arguments[0];", "macon").toString();
That code won't run. It'll throw a NullPointerException. I can avoid it by not trying to access the passed variable. It doesn't seem to matter what I pass; could be an int, string, WebElement, etc etc.
So what's wrong? I can't see any discrepancies between online examples and my code, but there's obviously something. I'm using the Firefox WebDriver, and my Selenium version is 2.44.0
You just need to cast the results to String:
JavaScriptExecutor js = (JavaScriptExecutor) driver;
String test = (String) js.executeScript("return arguments[0];", "macon");
Also, there were compatibility issues between selenium 2.44 and Firefox 35/36 which affected javascript code execution:
Firefox 35: Passing arguments to executeScript isn't working
Try this code:
JavaScriptExecutor js = (JavaScriptExecutor) driver;
String example=(String)js.executeScript('return $('table tbodt tr td:eq(0)')') .text();

how to return a string from JavascriptExecutor in java

I'm trying to pick up the string returned from JavascriptExecutor called from Java (the first time I've ever used it). I've seen several other posts on SO but they all stop before you get the string into Java.
Searching the internet, everybody says this should work:
JavascriptExecutor js =(JavascriptExecutor) driver;
js.executeScript("return document.title");
String CatchS = js.toString();
System.out.println("Output from javascript:" + CatchS);
but all that I get is Output from javascript:FirefoxDriver: firefox on XP (506d8fd0-0ce2-4693-8e56-2166a77a5136)
Which is exactly the same as you get from JavascriptExecutor if you feed it deliberately invalid JavaScript (i.e. this is it not working).
I've also tried the alternatives suggested in Get Value from ExecuteScript from JavaScriptExecutor, and even tried just returning 'hello world'. Nothing works. What am I missing?
I need it to return a string as that is what the real code I'm trying to insert will do (once it's working). Thank you.
When I execute the following
String CatchS = (String) js.executeScript("return document.title");
I get an exception of
Exception in thread "main" java.lang.Error: Unresolved compilation problem: Type mismatch: cannot convert from Object to String.

selecting list value by index number using selenium java

I tried using the select() method in my code, but Eclipse is showing an error. Is select() an inbuilt method of Selenium? I don't get it.
select(driver2.findElement(By.xpath("//*#id='webLossReport.contact.address.state']")),index=i);
Eclipse says "The method select(WebElement, int) is undefined for the type entry" and it is giving me an option to create a method in this class.
Please let me know how others are using it. My requirement is to "select a list value based on Index number"
Update: Code Posted as requested,
WebElement LSD = driver2.findElement(By.xpath("//select[#id='webLossReport.lossInformation.locationOfLoss.state']"));
List <WebElement> LLS = LossStateDropdown.findElements(By.tagName("option"));
int i= LLS.size();
select(driver2.findElement(By.xpath("//*#id='webLossReport.contact.address.state']")),index=i);
You're somehow lost between Selenium RC and Selenium WebDriver. Assuming you want to use WebDriver, see this doc, it explains it all.
You can either do the following - it directly finds the third <option> tag in the specified <select> and clicks it:
driver.findElement(By.xpath("id('selectsId')/option[3]")).click();
or this using the Select class:
Select sel = new Select(driver.findElement(By.id("selectsId")));
sel.selectByIndex(3);
In C#, I solved using this:
selenium.Select("id=yourID", "index=" + i.ToString());
I'm not familiar with this library, but the Selenium reference page gives the following signature for select:
select(java.lang.String selectLocator, java.lang.String optionLocator)
In your code, the second argument is index=i which is assigning index to the value of i, and then returning that int. What string were you planning on passing as the second argument? "index=i"? "index=" + i?

Categories