executePhantomJS on Remotewebdriver - java

if I use a web driver then it works perfectly
driver = new PhantomJSDriver(capabilities);
driver.executePhantomJS( "var page = this;");
How can I make it work?
driver = new RemoteWebDriver(capabilities);
driver.executePhantomJS( "var page = this;");
UPDATE
My code
capabilities = DesiredCapabilities.phantomjs();
driver = new RemoteWebDriver(capabilities);
driver.executePhantomJS( "var page = this; binary =0;mimetype=''; count = 0;id=0; bla = '{';"
+"page.onResourceReceived = function(request) {"
+ "if(id !== request.id){"
+"bla += '\"'+count+ '\":'+JSON.stringify(request, undefined, 4)+',';"
+"if(request.contentType.substring(0, 11) =='application'){"
+"console.log(request.contentType);"
+ "mimetype = request.contentType;"
+ "binary++;"
+ "}"
+"count++;"
+ "id = request.id;"
+ "}"
+"};");
Java gives error: The method executePhantomJS(String) is undefined for the type RemoteWebDriver.
If i use executeScript it will not work.
I need run 100 test parallel, i can't use webdriver.

I guess that you wanna run PhantomJSDriver on your Se Grid. This is how it works for me (C# Factory implementation):
public IWebDriver CreateWebDriver(string identifier)
{
if (identifier.ToLower().Contains("ghostdriver"))
{
return new RemoteWebDriver(new Uri(ConfigurationManager.AppSettings["Selenium.grid.Url"]), DesiredCapabilities.PhantomJS());
}
}
or try this one
Console.WriteLine("Creating GhostDriver (PhantomJS) driver.");
//Temporary commented for testing purposes
IWebDriver ghostDriver = new PhantomJSDriver("..\\..\\..\\MyFramework\\Drivers");
ghostDriver.Manage().Window.Maximize();
//ghostDriver.Manage().Window.Size = new Size(1920, 1080);
ghostDriver.Manage()
.Timeouts()
.SetPageLoadTimeout(new TimeSpan(0, 0, 0,
Convert.ToInt32(ConfigurationManager.AppSettings["Driver.page.load.time.sec"])));
return ghostDriver;
In case that you wonder why there is ConfigurationManager - I avoid the hard-coded values, so they are extracted from the App.config file.

If you want to run PhantomJS scripts with RemoteWebDriver (for using the Selenium Grid), I used the following solution (only C# unfortunately):
I had to extend the RemoteWebDriver so it can run PhantomJS commands:
public class RemotePhantomJsDriver : RemoteWebDriver
{
public RemotePhantomJsDriver(Uri remoteAddress, ICapabilities desiredCapabilities) : base(remoteAddress, desiredCapabilities)
{
this.CommandExecutor.CommandInfoRepository.TryAddCommand("executePhantomScript", new CommandInfo("POST", $"/session/{this.SessionId.ToString()}/phantom/execute"));
}
public Response ExecutePhantomJSScript(string script, params object[] args)
{
return base.Execute("executePhantomScript", new Dictionary<string, object>() { { "script", script }, { "args", args } });
}
}
After this you can use the ExecutePhantomJSScript method to run any JavaScript code that wants to interact with the PhantomJS API. The following example gets the page title trough the PhantomJS API (Web Page Module):
RemotePhantomJsDriver driver = new RemotePhantomJsDriver(new Uri("http://hub_host:hub_port/wd/hub"), DesiredCapabilities.PhantomJS());
driver.Navigate().GoToUrl("http://stackoverflow.com");
var result = driver.ExecutePhantomJSScript("var page = this; return page.title");
Console.WriteLine(result.Value);
driver.Quit();

Related

Different results by different methods on Chrome Performance Metrics?

I am writing some code to automate calculating certain page performance metrics. The results I am getting for page size are different by different methods:
What I want to achieve is to read these values shown in this screenshot:
Methods I am using:
Method giving different page load time and different transferred sizes:
Totalbytes and NetData return very different numbers, both very far from what the screenshot would show
public void testing() throws HarReaderException {
JavascriptExecutor js1=((JavascriptExecutor)driver);
try {
Thread.sleep(5000);
}catch(Exception e) {e.printStackTrace();}
String url=driver.getCurrentUrl();
System.out.println("Current URL :"+url);
long pageLoadTime= (Long)js1.executeScript("return (window.performance.timing.loadEventEnd-window.performance.timing.responseStart)");
long TTFB= (Long)js1.executeScript("return (window.performance.timing.responseStart-window.performance.timing.navigationStart)");
long endtoendRespTime= (Long)js1.executeScript("return (window.performance.timing.loadEventEnd-window.performance.timing.navigationStart)");
Date date = new Date();
//Timestamp ts=new Timestamp(date.getTime());
System.out.println("PageLoadTime Time :"+pageLoadTime);
System.out.println("TTFB :"+TTFB);
System.out.println("Customer perceived Time :"+endtoendRespTime);
System.out.println("timeStamp");
String scriptToExecute = "var performance = window.performance || window.mozPerformance || window.msPerformance || window.webkitPerformance || {}; var network = performance.getEntries() || {}; return network;";
String netData = ((JavascriptExecutor)driver).executeScript(scriptToExecute).toString();
System.out.println("Net data: " + netData);
String anotherScript = "return performance\n" +
" .getEntriesByType(\"resource\")\n" +
" .map((x) => x.transferSize)\n" +
" .reduce((a, b) => (a + b), 0);"; //I have tried encodedSize here as well, still gives different results
System.out.println("THIS IS HOPEFULLY THE TOTAL TRANSFER SIZE " + js1.executeScript((anotherScript)).toString());
int totalBytes = 0;
for (LogEntry entry : driver.manage().logs().get(LogType.PERFORMANCE)) {
if (entry.getMessage().contains("Network.dataReceived")) {
Matcher dataLengthMatcher = Pattern.compile("dataLength\":(.*?),").matcher(entry.getMessage()); //I tried encodedLength and other methods but always get different results from the actual page
dataLengthMatcher.find();
totalBytes = totalBytes + Integer.parseInt(dataLengthMatcher.group(1));
//Do whatever you want with the data here.
}
}
System.out.println(totalBytes);
}
Setting up selenium Chrome driver, enabling performance logging and mobbrowser proxy:
#BeforeTest
public void setUp() {
// start the proxy
proxy = new BrowserMobProxyServer();
proxy.start(0);
//get the Selenium proxy object - org.openqa.selenium.Proxy;
Proxy seleniumProxy = ClientUtil.createSeleniumProxy(proxy);
// configure it as a desired capability
DesiredCapabilities capabilities = new DesiredCapabilities().chrome();
LoggingPreferences logPrefs = new LoggingPreferences();
logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
capabilities.setCapability(CapabilityType.LOGGING_PREFS, logPrefs);
capabilities.setCapability(CapabilityType.PROXY, seleniumProxy);
ChromeOptions options = new ChromeOptions();
options.addArguments("--incognito");
capabilities.setCapability(ChromeOptions.CAPABILITY, options);
//set chromedriver system property
System.setProperty("webdriver.chrome.driver", driverPath);
driver = new ChromeDriver(capabilities);
// enable more detailed HAR capture, if desired (see CaptureType for the complete list)
proxy.enableHarCaptureTypes(CaptureType.REQUEST_CONTENT, CaptureType.RESPONSE_CONTENT);
}
Methods I am using to analyze the page:
This method was supposed to show the Load Time in chrome inspector, but it is always showing a lesser number (I think it is showing the time of the last response received instead of DOMContentLoaded or Load Time)
public double calculatePageLoadTime(String filename) throws HarReaderException {
HarReader harReader = new HarReader();
de.sstoehr.harreader.model.Har har = harReader.readFromFile(new File(filename));
HarLog log = har.getLog();
// Access all pages elements as an object
long startTime = log.getPages().get(0).getStartedDateTime().getTime();
// Access all entries elements as an object
List<HarEntry> hentry = log.getEntries();
long loadTime = 0;
int entryIndex = 0;
//Output "response" code of entries.
for (HarEntry entry : hentry)
{
long entryLoadTime = entry.getStartedDateTime().getTime() + entry.getTime();
if(entryLoadTime > loadTime){
loadTime = entryLoadTime;
}
entryIndex++;
}
long loadTimeSpan = loadTime - startTime;
Double webLoadTime = ((double)loadTimeSpan) / 1000;
double webLoadTimeInSeconds = Math.round(webLoadTime * 100.0) / 100.0;
return webLoadTimeInSeconds;
}
I am getting the total number of requests by reading the HAR file from the page, but for some reason it is always 10% less then the actual:
public int getNumberRequests(String filename) throws HarReaderException {
HarReader harReader = new HarReader();
de.sstoehr.harreader.model.Har har = harReader.readFromFile(new File(filename));
HarLog log = har.getLog();
return log.getEntries().size();
}
Testing this on google gives very different results by each method, which are usually 10-200% off from correct numbers.
Why does this happen? Is there a simple way to get those metrics properly from Chrome or any library that makes this easier? My task is automate doing performance analysis on thousands of pages.
I personally analyzed this on my system over and over again and came up with this -
The resource size which its showing currently is the amount of resource fetched till page load event is triggered.
So to overcome this you need to capture the the resource size variable after the page load event also until it stabilizes.Then it will match the actual console values.

PhantomJSDriver: Not able to switch to newly opened browser window

I have been trying to use PhantomJSWebDriver framework for automating an application using Headless browser. The main issue is as we can successfully switch between windows in firefox or IE windows, here I am not able to switch between windows based on handles. Please help me.
Below is the code I have tried so far.
System.setProperty("phantomjs.binary.path", file.getAbsolutePath());
driver = new PhantomJSDriver();
driver.get(application url);
driver.manage().timeouts().implicitlyWait(100, TimeUnit.SECONDS);
WebElement txtUsername = driver.findElement(By.id("it_C_C5"));
txtUsername.sendKeys("sreenis");
WebElement txtPassword = driver.findElement(By.id("it_C_C7"));
txtPassword.sendKeys("sreeni");
WebElement btnLogin = driver.findElement(By.id("ic_C_C8"));
btnLogin.click();
Thread.sleep(10000);
String winTitle = "Role profile selection";
boolean bool = switchWindow(winTitle);
if (bool){
System.out.println("Page title is: " + driver.getTitle());
driver.quit();
}
else {
System.out.println("Switch to window '" + winTitle + "' failed!");
driver.quit();
}
public static boolean switchWindow(String windowtitle){
String mainWindowsHandle = driver.getWindowHandle();
Set<String> handles = driver.getWindowHandles();
System.out.println(handles.size());
for(String winHandle : handles){
driver.switchTo().window(winHandle);
System.out.println(driver.getTitle());
if(driver.getTitle().toLowerCase().equals(windowtitle)){
return true;
}
}
driver.switchTo().window(mainWindowsHandle);
return false;
}
When I tried to print the window titles in collection, it is only printing the parent window and not the other windows. I am not able to guess what is happening since nothing can be seen and it is headless testing. Please suggest me is there any other way so that I can test the app with many browser windows.
Actions act = new Actions(d);
act.contextClick(elements).sendKeys("W").perform();
Set<String> win = d.getWindowHandles();
Iterator <String> itrwin = win.iterator();
String parent = itrwin.next();
String child = itrwin.next();
d.switchTo().window(child);
identify an web element first using findElement() and store it in element.

Selenium webdriver not logging into live.com

I've been attempting to login to live.com with the Selenium Webdriver however every attempt results in an invalid email or password. A correct login is used. I tested it in a physical browser. I'm uncertain if this is the case but I believe sendkeys is not working. Code below.
protected static Map<String,String> settings = new HashMap<String,String>();
public static WebDriver pwb;
In Main:
// Default settings
settings.put("browser","chrome");
settings.put("os","WINDOWS8");
// Sort arguments and put into HashMap
grab(args);
// Set browser settings
DesiredCapabilities cap = DesiredCapabilities.htmlUnitWithJs();
cap.setBrowserName(settings.get("browser"));
cap.setPlatform(Platform.extractFromSysProperty(settings.get("os")));
d.log(cap.asMap().toString());
// Create web browser object
pwb = new HtmlUnitDriver(cap);
login();
In login():
Load("http://login.live.com",0); // custom load function
d.log(pwb.getTitle());
if(pwb.getTitle().contains("Sign in to your")){ // Full login
d.log("Executing full login.\nEmail:" + settings.get("email") + "\nPassword:"+settings.get("password"));
// if (pwb instanceof JavascriptExecutor) {
// ((JavascriptExecutor) pwb).executeScript("document.getElementsByName('login')[0].click();"); //value = " + settings.get("email") + "");
// ((JavascriptExecutor) pwb).executeScript("document.getElementsByName('passwd')[0].click();"); //.value = " + settings.get("password") + "");
// }
// TODO get login working
pwb.findElement(By.id("i0116")).clear();
pwb.findElement(By.id("i0116")).sendKeys(settings.get("email"));
pwb.findElement(By.id("i0118")).clear();
pwb.findElement(By.id("i0118")).sendKeys(settings.get("password"));
pwb.findElement(By.name("SI")).click();
// Attempted = true;
}
If anymore information is needed please let me know.

can not instantiate driver class in Meteor method

I am trying to use JDBC inside my meteor application but I was not successful in loading the driver class.
the code is simple enough:
console.log("testing jdbc " + process.env.PWD + "/server/ojdbc14-11.2.jar");
var java = Meteor.require('java');
java.classpath.push(process.env.PWD + '/server/ojdbc14-11.2.jar');
console.log("class loaded");
var driver = java.newInstanceSync('oracle.jdbc.driver.OracleDriver');
console.log("driver instantiated");
var result = java.callStaticMethodSync('java.sql.DriverManager','registerDriver', driver);
console.log("driver registered");
result = java.callStaticMethodSync('java.sql.DriverManager','getConnection', 'jdbc:oracle:thin:user/password#local.sertal.ch:7788/KND1');
console.log("connection established");
I am using the Meteor npm package to include java the console never shows the message driver instantiated
I tried the same thing with a naked nodejs script and it worked fine. The code is almost the same:
var java = require('java');
java.classpath.push(__dirname + '/ojdbc14-11.2.jar');
var driver = java.newInstanceSync('oracle.jdbc.driver.OracleDriver');
var result = java.callStaticMethodSync('java.sql.DriverManager','registerDriver', driver);
var connection = java.callStaticMethodSync('java.sql.DriverManager', 'getConnection', 'jdbc:oracle:thin:user/password#local.sertal.ch:7788/KND1');

How to use JavaScript with Selenium WebDriver Java

I want to use JavaScript with WebDriver (Selenium 2) using Java.
I've followed some a guide and on Getting Started page: there is an instruction at 1st line to run as:
$ ./go webdriverjs
My question: From which folder/location the command mentioned above will be run/executed?
Based on your previous questions, I suppose you want to run JavaScript snippets from Java's WebDriver. Please correct me if I'm wrong.
The WebDriverJs is actually "just" another WebDriver language binding (you can write your tests in Java, C#, Ruby, Python, JS and possibly even more languages as of now). This one, particularly, is JavaScript, and allows you therefore to write tests in JavaScript.
If you want to run JavaScript code in Java WebDriver, do this instead:
WebDriver driver = new AnyDriverYouWant();
if (driver instanceof JavascriptExecutor) {
((JavascriptExecutor)driver).executeScript("yourScript();");
} else {
throw new IllegalStateException("This driver does not support JavaScript!");
}
I like to do this, also:
WebDriver driver = new AnyDriverYouWant();
JavascriptExecutor js;
if (driver instanceof JavascriptExecutor) {
js = (JavascriptExecutor)driver;
} // else throw...
// later on...
js.executeScript("return document.getElementById('someId');");
You can find more documentation on this here, in the documenation, or, preferably, in the JavaDocs of JavascriptExecutor.
The executeScript() takes function calls and raw JS, too. You can return a value from it and you can pass lots of complicated arguments to it, some random examples:
1.
// returns the right WebElement
// it's the same as driver.findElement(By.id("someId"))
js.executeScript("return document.getElementById('someId');");
// draws a border around WebElement
WebElement element = driver.findElement(By.anything("tada"));
js.executeScript("arguments[0].style.border='3px solid red'", element);
// changes all input elements on the page to radio buttons
js.executeScript(
"var inputs = document.getElementsByTagName('input');" +
"for(var i = 0; i < inputs.length; i++) { " +
" inputs[i].type = 'radio';" +
"}" );
JavaScript With Selenium WebDriver
Selenium is one of the most popular automated testing suites.
Selenium is designed in a way to support and encourage automation testing of functional aspects of web based applications and a wide range of browsers and platforms.
public static WebDriver driver;
public static void main(String[] args) {
driver = new FirefoxDriver(); // This opens a window
String url = "----";
/*driver.findElement(By.id("username")).sendKeys("yashwanth.m");
driver.findElement(By.name("j_password")).sendKeys("yashwanth#123");*/
JavascriptExecutor jse = (JavascriptExecutor) driver;
if (jse instanceof WebDriver) {
//Launching the browser application
jse.executeScript("window.location = \'"+url+"\'");
jse.executeScript("document.getElementById('username').value = \"yash\";");
// Tag having name then
driver.findElement(By.xpath(".//input[#name='j_password']")).sendKeys("admin");
//Opend Site and click on some links. then you can apply go(-1)--> back forword(-1)--> front.
//Refresheing the web-site. driver.navigate().refresh();
jse.executeScript("window.history.go(0)");
jse.executeScript("window.history.go(-2)");
jse.executeScript("window.history.forward(-2)");
String title = (String)jse.executeScript("return document.title");
System.out.println(" Title Of site : "+title);
String domain = (String)jse.executeScript("return document.domain");
System.out.println("Web Site Domain-Name : "+domain);
// To get all NodeList[1052] document.querySelectorAll('*'); or document.all
jse.executeAsyncScript("document.getElementsByTagName('*')");
String error=(String) jse.executeScript("return window.jsErrors");
System.out.println("Windowerrors : "+error);
System.out.println("To Find the input tag position from top");
ArrayList<?> al = (ArrayList<?>) jse.executeScript(
"var source = [];"+
"var inputs = document.getElementsByTagName('input');"+
"for(var i = 0; i < inputs.length; i++) { " +
" source[i] = inputs[i].offsetParent.offsetTop" + //" inputs[i].type = 'radio';"
"}"+
"return source"
);//inputs[i].offsetParent.offsetTop inputs[i].type
System.out.println("next");
System.out.println("array : "+al);
// (CTRL + a) to access keyboard keys. org.openqa.selenium.Keys
Keys k = null;
String selectAll = Keys.chord(Keys.CONTROL, "a");
WebElement body = driver.findElement(By.tagName("body"));
body.sendKeys(selectAll);
// Search for text in Site. Gets all ViewSource content and checks their.
if (driver.getPageSource().contains("login")) {
System.out.println("Text present in Web Site");
}
Long clent_height = (Long) jse.executeScript("return document.body.clientHeight");
System.out.println("Client Body Height : "+clent_height);
// using selenium we con only execute script but not JS-functions.
}
driver.quit(); // to close browser
}
To Execute User-Functions, Writing JS in to a file and reading as String and executing it to easily use.
Scanner sc = new Scanner(new FileInputStream(new File("JsFile.txt")));
String js_TxtFile = "";
while (sc.hasNext()) {
String[] s = sc.next().split("\r\n");
for (int i = 0; i < s.length; i++) {
js_TxtFile += s[i];
js_TxtFile += " ";
}
}
String title = (String) jse.executeScript(js_TxtFile);
System.out.println("Title : "+title);
document.title & document.getElementById() is a property/method available in Browsers.
JsFile.txt
var title = getTitle();
return title;
function getTitle() {
return document.title;
}
You can also try clicking by JavaScript:
WebElement button = driver.findElement(By.id("someid"));
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("arguments[0].click();", button);
Also you can use jquery. In worst cases, for stubborn pages it may be necessary to do clicks by custom EXE application. But try the obvious solutions first.
I didn't see how to add parameters to the method call, it took me a while to find it, so I add it here.
How to pass parameters in (to the javascript function), use "arguments[0]" as the parameter place and then set the parameter as input parameter in the executeScript function.
driver.executeScript("function(arguments[0]);","parameter to send in");
If you want to read text of any element using javascript executor, you can do something like following code:
WebElement ele = driver.findElement(By.xpath("//div[#class='infaCompositeViewTitle']"));
String assets = (String) js.executeScript("return arguments[0].getElementsByTagName('span')[1].textContent;", ele);
In this example, I have following HTML fragment and I am reading "156".
<div class="infaCompositeViewTitle">
<span>All Assets</span>
<span>156</span>
</div>
Following code worked for me:
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.springframework.beans.factory.annotation.Autowired;
public class SomeClass {
#Autowired
private WebDriver driver;
public void LogInSuperAdmin() {
((JavascriptExecutor) driver).executeScript("console.log('Test test');");
}
}
I had a similar situation and solved it like this:
WebElement webElement = driver.findElement(By.xpath(""));
webElement.sendKeys(Keys.TAB);
webElement.sendKeys(Keys.ENTER);
You need to run this command in the top-level directory of a Selenium SVN repository checkout.

Categories

Resources