How is this achieved? Here it says the java version is:
WebDriver driver; // Assigned elsewhere
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("return document.title");
But I can't find the C# code to do this.
The object, method, and property names in the .NET language bindings do not exactly correspond to those in the Java bindings. One of the principles of the project is that each language binding should "feel natural" to those comfortable coding in that language. In C#, the code you'd want for executing JavaScript is as follows
IWebDriver driver; // assume assigned elsewhere
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
string title = (string)js.ExecuteScript("return document.title");
Note that the complete documentation of the WebDriver API for .NET can be found at this link.
I prefer to use an extension method to get the scripts object:
public static IJavaScriptExecutor Scripts(this IWebDriver driver)
{
return (IJavaScriptExecutor)driver;
}
Used as this:
driver.Scripts().ExecuteScript("some script");
the nuget package Selenium.Support already contains an extension method to help with this. Once it is included, one liner to executer script
Driver.ExecuteJavaScript("console.clear()");
or
string result = Driver.ExecuteJavaScript<string>("console.clear()");
How about a slightly simplified version of #Morten Christiansen's nice extension method idea:
public static object Execute(this IWebDriver driver, string script)
{
return ((IJavaScriptExecutor)driver).ExecuteScript(script);
}
// usage
var title = (string)driver.Execute("return document.title");
or maybe the generic version:
public static T Execute<T>(this IWebDriver driver, string script)
{
return (T)((IJavaScriptExecutor)driver).ExecuteScript(script);
}
// usage
var title = driver.Execute<string>("return document.title");
You could also do:
public static IWebElement FindElementByJs(this IWebDriver driver, string jsCommand)
{
return (IWebElement)((IJavaScriptExecutor)driver).ExecuteScript(jsCommand);
}
public static IWebElement FindElementByJsWithWait(this IWebDriver driver, string jsCommand, int timeoutInSeconds)
{
if (timeoutInSeconds > 0)
{
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
wait.Until(d => d.FindElementByJs(jsCommand));
}
return driver.FindElementByJs(jsCommand);
}
public static IWebElement FindElementByJsWithWait(this IWebDriver driver, string jsCommand)
{
return FindElementByJsWithWait(driver, jsCommand, s_PageWaitSeconds);
}
public void javascriptclick(String element)
{
WebElement webElement=driver.findElement(By.xpath(element));
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].click();",webElement);
System.out.println("javascriptclick"+" "+ element);
}
public static class Webdriver
{
public static void ExecuteJavaScript(this IWebDriver driver, string scripts)
{
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
js.ExecuteScript(scripts);
}
public static T ExecuteJavaScript<T>(this IWebDriver driver, string scripts)
{
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
return (T)js.ExecuteScript(scripts);
}
}
In your code you can then do:
IWebDriver driver = new WhateverDriver();
string test = driver.ExecuteJavaScript<string>(" return 'hello World'; ");
int test = driver.ExecuteJavaScript<int>(" return 3; ");
Please use the below extension methods added to execute javascript and to take screenshot in Selenium.Support (.dll) of Selenium C#
https://www.nuget.org/packages/Selenium.Support/
IWebDriver driver = new ChromeDriver();
driver.Manage().Window.Maximize();
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(20);
driver.Url = "https://phptravels.net/";
driver.ExecuteJavaScript("document.querySelector('#checkin').value='07-12-2022'");
driver.ExecuteJavaScript("document.querySelector('#checkout').value='17-12-2022'");
IWebElement ele1 = driver.FindElement(By.Id("checkin"));
driver.ExecuteJavaScript("arguments[0].value='07-12-2022'",ele1);
string output=driver.ExecuteJavaScript<string>("return
document.querySelector('#checkin').value");
Console.WriteLine(output);
Screenshot sc= driver.TakeScreenshot();
sc.SaveAsFile("C:\\error.png");
The shortest code
ChromeDriver drv = new ChromeDriver();
drv.Navigate().GoToUrl("https://stackoverflow.com/questions/6229769/execute-javascript-using-selenium-webdriver-in-c-sharp");
drv.ExecuteScript("return alert(document.title);");
Related
I am currently working on an app where i use a webview to display a webapp. I want to make it so that a user does not have to type his username everytime he starts the app . I want to automatically fill the textbox in the webview with text from c#. I have the following code untill now but I think my javascript is far from good (I don't have any specific knowledge about javascript).
private async void asyncjevoordeuser()
{
var inputValue = "test";
var functionString = string.Format(#"document.getElementById('username');", inputValue);
await WebView.InvokeScriptAsync("eval", new string[] { functionString });
}
I am calling this method from
private void WebView_LoadCompleted(object sender, NavigationEventArgs e)
{
asyncjevoordeuser();
}
I hope someone can help me out.
await WebViewObj.InvokeScriptAsync("eval", new string[] { "document.getElementById('username').value = 'username here';" });
I want to retrieve data from a website using Nashorn script engine
I have the java code where I can retrieve data from a sample website template.
Now I want to call that java file from java script file.
following is the code:
JAVA CODE(Nsample.java):
package sample;
import java.net.*;
import java.io.*;
public class Nsample
{
public static void main(String[] args)
{
String output = getUrlContents("https://freewebsitetemplates.com/");
System.out.println(output);
}
public static String getUrlContents(String theUrl)
{
StringBuilder content = new StringBuilder();
try
{
URL url = new URL(theUrl);
URLConnection urlConnection = url.openConnection();
BufferedReader bufferedReader = new BufferedReader(new
InputStreamReader(urlConnection.getInputStream()));
String line;
while ((line = bufferedReader.readLine()) != null)
{
content.append(line + "\n");
}
bufferedReader.close();
}
catch(Exception e)
{
e.printStackTrace();
}
return content.toString();
}
}
JAVASCRIPT code:(sample.js)
var n = Java.type('C.JavaFolder.sample.Nsample');
var result = n.getUrlContents("https://freewebsitetemplates.com/");
print(result);
I'm trying to compile javascript code using command prompt but it is showing CLASSNOTFOUNDEXCEPTION.
The command was jjs sample.js.Im assuming I did some mistake in Java.type() function.
Can anyone solve this?
This line is the problematic line:
var n = Java.type('C.JavaFolder.sample.Nsample');
Java.type accepts fully qualified java type name. Based on your Java code, your package seems to be "sample" and class name is "Nsample". So the fully qualified class name would be "sample.Nsample".
You should compile your Java classes and specify the directory in -classpath option (of jjs tool or your java application if you use javax.script API with nashorn).
Instead of calling Java from JavaScript , I tried to call JavaScript from java and worked well.
I created some functions in JavaScript and invoked those functions from Java code.
Following is the code.Hope this helps.
Test.java:
import javax.script.*;
import java.io.*;
import java.util.*;
public class Test{
public static void main(String[] args) throws Exception{
ScriptEngine engine = new ScriptEngineManager().getEngineByName("Nashorn");
engine.eval(new FileReader("test.js"));
Invocable invoke = (Invocable)engine;
Object res = invoke.invokeFunction("httpGet","https://www.javaworld.com");
System.out.println(res);
}
}
test.js:
var httpGet = function(theUrl){
var con = new java.net.URL(theUrl).openConnection();
con.requestMethod = "GET";
return asResponse(con);
}
function asResponse(con){
var d = read(con.inputStream);
return d;
}
function read(inputStream){
var inReader = new java.io.BufferedReader(new
java.io.InputStreamReader(inputStream));
var inputLine;
var response = new java.lang.StringBuffer();
while ((inputLine = inReader.readLine()) != null) {
response.append(inputLine);
}
inReader.close();
return response.toString();
}
Below is the snippet and getting error as follows :
The method executeScript(String, Object[]) in the type JavascriptExecutor is not applicable for the arguments (String)
Code Snippet :
public class ScrollPage {
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver", "C:\\SeleniumWorkSpace\\chromeDriver\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
System.out.println(driver);
driver.get("https://en.wikipedia.org/wiki/Main_Page");
driver.manage().window().maximize();
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript("scroll(0,2500)");
}
}
How would I fix this?
Try to use it without casting
driver.executeScript("scroll(0,2500)");
Edit the line of code as :
//import
import org.openqa.selenium.JavascriptExecutor;
//cast driver instance to JavascriptExecutor
JavascriptExecutor js = (JavascriptExecutor)driver;
//invove executeScript method
js.executeScript("scroll(0, 2500)");
Note : Put a space between the coordinates
Try this code:
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript("window.scrollTo(0,2500);");
Please try the following - I was having the same error with JavascriptExecutor not performing scroll downs properly.
public WebElement pollingScroll(By locator) {
WebDriverWait shortWait = new WebDriverWait(driver, 1);
WebElement element = null;
while(element == null) {
((JavascriptExecutor) driver).executeScript("window.scrollBy(0, 555);");
try {
element =
shortWait.until(ExpectedConditions.elementToBeClickable(locator));
} catch(Exception e) {}
}
return element;
}
public boolean WaitForPageToLoad(){
final ExpectedCondition<Boolean> pageLoadCondition = new ExpectedCondition<Boolean>() {
public Boolean apply(final WebDriver driver) {
return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete");
}
};
final WebDriverWait wait = new WebDriverWait(this.driver, this.defaultTimeoutinSeconds);
final boolean IsPageLoad = wait.until(pageLoadCondition);
if (!IsPageLoad) {
log.logInfo("Page doesn't load after " + this.defaultTimeoutinSeconds + " seconds");
}
return IsPageLoad;
}
above code was working in selenium 2.53.1 but when I upgraded to Selenium 3.1.X, above code is not compatible. Plaese anyone convert above code to make it compatible with selenium 3. I am getting below error
The method until(Function) in the type FluentWait is not applicable for the arguments (new ExpectedCondition(){})
This code works for me for Selenium3
driver = (new Driver(Driver.Browser.SAFARI)).getDriver();
driver.navigate().to("http://www.epochconverter.com/");
waitForLoad(driver);
static void waitForLoad(WebDriver driver) {
new WebDriverWait(driver, 50).until((ExpectedCondition<Boolean>) wd ->
((JavascriptExecutor) wd).executeScript("return document.readyState").equals("complete"));
}
I am working on a project that requires that a Java class be called from a piece of Javascript that was executed by a separate piece of Java code. It did originally work in Java 7.51 but it needs to work in Java 1.6.0_27 as well but fails with a function importclass must be called with a class error message.
The two JARs were generated through Eclipse Indigo using the Export > JAR command.
I created a simple MCVE as below to demonstrate the problem. The stack trace from executing with the following command line...
java -cp Sanity.jar;SanityCheck.jar -jar SanityCheck.jar
...is the following:
javax.script.ScriptException: sun.org.mozilla.javascript.internal.EvaluatorException: Function importClass must be called with a class; had "[JavaPackage com.sanity.Sanity]" instead. (<Unknown source>#1) in <Unknown source> at line number 1
at com.sun.script.javascript.RhinoScriptEngine.eval(Unknown Source)
at com.sun.script.javascript.RhinoScriptEngine.eval(Unknown Source)
at javax.script.AbstractScriptEngine.eval(Unknown Source)
at com.sanity.SanityCheck.<init>(SanityCheck.java:22)
at com.sanity.SanityCheck.main(SanityCheck.java:52)
Exception in thread "main" java.lang.NullPointerException
at com.sanity.SanityCheck.invoke(SanityCheck.java:31)
at com.sanity.SanityCheck.main(SanityCheck.java:53)
Can anyone see where I am going wrong here?
Sanity.java (in its own JAR of the same name)
package com.sanity;
public class Sanity {
public Sanity() {}
public void doCheck() {
System.out.println("Sanity Check Passed!");
}
}
SanityCheck.java (in its own JAR of the same name)
package com.sanity;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class SanityCheck {
private Invocable invoker;
public SanityCheck(String script) {
try {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
engine.eval(script);
invoker = (Invocable) engine;
} catch (ScriptException e) {
e.printStackTrace();
}
}
public void invoke() {
try {
invoker.invokeFunction("run");
} catch (ScriptException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
StringBuilder builder = new StringBuilder();
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("Sanity.js")));
String line = null;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
reader.close();
SanityCheck check = new SanityCheck(builder.toString());
check.invoke();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Sanity.js
importClass(Packages.com.sanity.Sanity);
function run() {
var sanObj = new Sanity();
sanObj.doCheck();
}
I have good news: the problem has nothing to do with your Java or JavaScript code. It has to do with the effect of the command:
java -cp [...] -jar <jar-file>
When executing that command, the -cp argument is ignored, and the <jar-file> is used as the entire classpath.
From the Java 6 documentation for the -jar option to the java tool:
When you use this option, the JAR file is the source of all user classes, and other user class path settings are ignored.
So a version of your command that would work is:
java -cp Sanity.jar;SanityCheck.jar com.sanity.SanityCheck
I reproduced your example with the following directory structure, without modifying your code:
Sanity.js
com/
sanity/
Sanity.java
SanityCheck.java
... and then ran the following command from the top-level directory:
$ /usr/lib/jvm/java-1.6.0-openjdk-amd64/bin/javac com/sanity/*.java && /usr/lib/jvm/java-1.6.0-openjdk-amd64/bin/java -classpath . com.sanity.SanityCheck
... and got
Sanity Check Passed!
The error was down to the JAR file that was being called from the Javascript was compiled against Java 7, not Java 6. A quick test trying to run a main method in Eclipse soon revealed this.
A quick recompilation of the JAR file and now it works.