How to open a html file available in local machine in selenium grid node - selenium

I have a html file in my local machine. When running my selenium-java code locally through eclipse, I can access the html file through the code mentioned below -
File file = new File(url);
driver.get("file:///" + file.getAbsolutePath());
If I run the code through selenium grid, registered node doesn't pick up the html file path to be opened in chrome since the absolute path points to the local machine.
Is there any solution available to open the locally available html file through selenium grid-node?

You should use a LocalFileDetector.
import org.openqa.selenium.remote.LocalFileDetector
import org.openqa.selenium.remote.RemoteWebDriver
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), DesiredCapabilities.firefox());
driver.setFileDetector(new LocalFileDetector())
Your upload should now work.

There are basically two ways in which you can get this done. I will list out both the approaches. Please feel free to pick and choose whichever works for you.
Using custom node servlet
You need to follow the below steps:
Create a new custom servlet, using which you can upload a file using a HTTP POST method.
It could look something like below [ This code is borrowed from a journaldev post here and being included here only for the sake of completeness] You may need to tweak the code before use and not necessarily use it as is. The current code returns a html response, but you may need to change it so that it returns a JSON response which contains the actual path where the file was uploaded to. This path is what you will use in your driver.get() call.
package com.journaldev.servlet;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
public class UploadDownloadFileServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private ServletFileUpload uploader = null;
#Override
public void init() throws ServletException{
DiskFileItemFactory fileFactory = new DiskFileItemFactory();
File filesDir = (File) getServletContext().getAttribute("FILES_DIR_FILE");
fileFactory.setRepository(filesDir);
this.uploader = new ServletFileUpload(fileFactory);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String fileName = request.getParameter("fileName");
if(fileName == null || fileName.equals("")){
throw new ServletException("File Name can't be null or empty");
}
File file = new File(request.getServletContext().getAttribute("FILES_DIR")+File.separator+fileName);
if(!file.exists()){
throw new ServletException("File doesn't exists on server.");
}
System.out.println("File location on server::"+file.getAbsolutePath());
ServletContext ctx = getServletContext();
InputStream fis = new FileInputStream(file);
String mimeType = ctx.getMimeType(file.getAbsolutePath());
response.setContentType(mimeType != null? mimeType:"application/octet-stream");
response.setContentLength((int) file.length());
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
ServletOutputStream os = response.getOutputStream();
byte[] bufferData = new byte[1024];
int read=0;
while((read = fis.read(bufferData))!= -1){
os.write(bufferData, 0, read);
}
os.flush();
os.close();
fis.close();
System.out.println("File downloaded at client successfully");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if(!ServletFileUpload.isMultipartContent(request)){
throw new ServletException("Content type is not multipart/form-data");
}
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.write("<html><head></head><body>");
try {
List<FileItem> fileItemsList = uploader.parseRequest(request);
Iterator<FileItem> fileItemsIterator = fileItemsList.iterator();
while(fileItemsIterator.hasNext()){
FileItem fileItem = fileItemsIterator.next();
System.out.println("FieldName="+fileItem.getFieldName());
System.out.println("FileName="+fileItem.getName());
System.out.println("ContentType="+fileItem.getContentType());
System.out.println("Size in bytes="+fileItem.getSize());
File file = new File(request.getServletContext().getAttribute("FILES_DIR")+File.separator+fileItem.getName());
System.out.println("Absolute Path at server="+file.getAbsolutePath());
fileItem.write(file);
out.write("File "+fileItem.getName()+ " uploaded successfully.");
out.write("<br>");
out.write("Download "+fileItem.getName()+"");
}
} catch (FileUploadException e) {
out.write("Exception in uploading file.");
} catch (Exception e) {
out.write("Exception in uploading file.");
}
out.write("</body></html>");
}
}
Create a sample project, which includes a dependency on the selenium libraries and which contains the servlet built in step (1) and create a jar out of it. For instructions on how to do all of this, you can refer to my blog post here (or) to the official selenium documentation here.
Start the node, along with the -servlets parameter so that your newly created node servlet, gets injected into the node and is available via http://<Node_IP_Address>:<Node_Port>/extra/UploadDownloadFileServlet (since our sample servlet's name was UploadDownloadFileServlet)
Now in your test code, you can create a new RemoteWebDriver instance as always.
You now need to upload your html file to the remote node where the new session was created. For doing that, you need to know the IP of the node where your test ran. So you make use of a library such as talk2grid (I built this library) or leverage the approach of determining this information on your own by referring to my blog here
Once you have the IP and port, you now trigger a HTTP POST to the servlet you created earlier by hitting the endpoint http://<Node_IP_Address>:<Node_Port>/extra/UploadDownloadFileServlet and get back the path to where it was uploaded in the response.
Now use the path that was returned in step (6) in your driver.get() call (don't forget to include the file:/// protocol)
That should do.
Using Javascript
In this approach, you basically start off by loading a blank page (for e.g., driver.get("about:blank"); and then make use of Javascript to start dynamically creating your web page via document.createElement() call (Refer to this article for more information ) and create the entire page. You can now start interacting with the page.
Approach (1) would be useful only when you are working with a grid environment wherein you are allowed to add servlets etc and access its IP and port.
Approach (2) will work in all use cases including third party remote execution environment providers such as SauceLabs or BrowserStack (In case you use them as well)

Related

Microsoft Edge WebDriver- Unable to use default app data profile for Automation - Edge Ver 80

I have to use existing user login session, we will require EDGE user profile, as we observed EDGE driver doesn't use the existing user data profile it is creating a new profile every time
EDGE Default Profile Path
C:\Users\edge2automation\AppData\Local\Microsoft\Edge\User Data\Default
(Edge driver) path -
C:\Users\edge2automation\AppData\Local\Temp\scoped_dir64860_1277252271\Default
As the new Edge is based on Chromium, we can refer to the solution of using Chrome profile and change the key words to Edge:
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeOptions;
public class Edgeauto {
public static void main(String[] args) {
System.setProperty("webdriver.edge.driver", "your\\path\\to\\edge\\webdriver\\msedgedriver.exe");
EdgeOptions edgeOptions = new EdgeOptions();
edgeOptions.addArguments("user-data-dir=C:\\Users\\edge2automation\\AppData\\Local\\Microsoft\\Edge\\User Data");
edgeOptions.addArguments("--start-maximized");
WebDriver driver = new EdgeDriver(edgeOptions);
driver.get("https://www.google.com/");
}
}
Please note that this needs to use selenium-server-4.0.0-alpha-4 which you can download form here.

How to execute Firefox developer console commands from Selenium?

I would like to execute Firefox's screenshot --fullpage command from inside a Selenium java script.
The command is documented in Take a full page screenshot with Firefox
Is it possible?
You can just take a screenshot from within your Java code. From this answer: https://stackoverflow.com/a/3423347/8020699
WebDriver driver = new FirefoxDriver();
driver.get("http://www.google.com/");
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
// Now you can do whatever you need to do with it, for example copy somewhere
FileUtils.copyFile(scrFile, new File("c:\\tmp\\screenshot.png"));
This guy suggests using a library called aShot to take full page screenshots. Here's the link to the aShot jar. Here's the code he gives:
import java.io.File;
import javax.imageio.ImageIO;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import ru.yandex.qatools.ashot.AShot;
import ru.yandex.qatools.ashot.Screenshot;
import ru.yandex.qatools.ashot.shooting.ShootingStrategies;
public class FullPageScreenshot {
public static void main(String args[]) throws Exception{
//Modify the path of the GeckoDriver in the below step based on your local system path
System.setProperty("webdriver.gecko.driver","D://Selenium Environment//Drivers//geckodriver.exe");
// Instantiation of driver object. To launch Firefox browser
WebDriver driver = new FirefoxDriver();
// To oepn URL "http://softwaretestingmaterial.com"
driver.get("http://www.softwaretestingmaterial.com");
Thread.sleep(2000);
Screenshot fpScreenshot = new AShot().shootingStrategy(ShootingStrategies.viewportPasting(1000)).takeScreenshot(driver);
ImageIO.write(fpScreenshot.getImage(),"PNG",new File("D:///FullPageScreenshot.png"));
}
}

selenium grid connction with autoit not working?

selenium grid connection with auto it not working ?
#daluudaluu/PartialSeleniumGridIntegrationWithAutoItExample.java
Last active a year ago
Embed
Download ZIP
Code Revisions 2 Forks 1
Partial Selenium Grid integration support with tools like AutoIt, Sikuli, etc.
Raw
PartialSeleniumGridIntegrationWithAutoItExample.java
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.remote.*;
import java.net.URL;
public class DemoTest {
public WebDriver driver;
public DesiredCapabilities capabilities;
#Before
public void setUp() throws Exception {
capabilities = DesiredCapabilities.firefox();
driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub" ), capabilities);
}
#After
public void tearDown() throws Exception {
driver.quit();
}
#Test
public void test() throws Exception {
// Use RemoteWebDriver, grab actual node host info
driver.get("http://www.google.com");
String sessionId = ((RemoteWebDriver) driver).getSessionId().toString();
//grid info extractor from: https://gist.github.com/krmahadevan/1766772
String nodeHost = GridInfoExtracter.getHostNameAndPort("localhost", 4444, sessionId)[0];
System.out.println("Extracted hostname: "+nodeHost);
// Now use node host info to handle running AutoIt on that specific node, assuming all needed files deployed to all nodes
// Case 1 - PSExec.exe from Windows host (that is executing this Selenium code) to Selenium node that is Windows host
//String psexecCmd = "C:\\LocalMachinePathTo\\psexec.exe \\\\%s -u %s -p %s -i C:\\GridNodeMachinePathTo\\autoitCompiledScript.exe";
//Process p = Runtime.getRuntime().exec(String.format(psexecCmd,nodeHost,"jdoe","hisPassword"));
//p.waitFor();
// Case 2 - winexe from *nix host (that is executing this Selenium code) to Selenium node that is Windows host
// Example reference: http://secpod.org/blog/?p=661
//String winexeCmd = "/LocalMachinePathTo/winexe -U domainName/jdoe%hisPassword //"+nodeHost+" C:\\GridNodeMachinePathTo\\autoitCompiledScript.exe";
//Process p = Runtime.getRuntime().exec(winexeCmd);
//p.waitFor();
// Case 3 - have SSH installed on Windows-based Selenium nodes, now just connect to node host via SSH to run a command, i.e. execute AutoIt script binary
// no sample code given for Java, but maybe this gives you ideas on Java SSH connection:
// http://stackoverflow.com/questions/995944/ssh-library-for-java
// Case 4 - if you have implemented a custom web service (XML-RPC/SOAP/REST) for AutoIt that listens for requests/commands
// just connect to it via (Java) HTTP library to "http://"+nodeHost+"/someWebServicePath/someCommand" (via GET or POST)
// details not covered, this is just an example. Most people won't be taking this route due to customization & complexity in
// building the web service first
// Case 5 - using AutoItDriverServer that is also running on Selenium nodes
//DesiredCapabilities autoitCapabilities = new DesiredCapabilities();
//autoitCapabilities.setCapability("browserName", "AutoIt");
//WebDriver autoitDriver = new RemoteWebDriver(new URL("http://"+nodeHost+":4723/wd/hub"), autoitCapabilities);
//autoitDriver.findElement(By.id("133")).click();
//and whatever other AutoItX commands to call that you normally have in the AutoIt script that you compile into binary
//for more ideas on AutoIt commands issued as WebDriver commands with respect to Selenium integration, see:
//https://github.com/daluu/AutoItDriverServer/blob/master/sample-code/SeleniumIntegrationWithAutoItDriver.py
//or if you are old school, and want to do that same approach even with AutoItDriverServer,
// assuming you have first set AutoItScriptExecuteScriptAsCompiledBinary to True in autoit_options.cfg file before starting AutoItDriverServer:
//((JavascriptExecutor) autoitDriver).executeScript("C:\\GridNodeMachinePathTo\\autoitCompiledScript.exe");
// Case for Sikuli integration, using https://github.com/enix12enix/sikuli-remote-control
//RemoteScreen rs = new RemoteScreen(nodeHost);
//rs.setMinSimilarity(0.9);
//rs.click("D://test.png");
}
}

Null Pointer Exception when running selenium webdriver testcase using internet explorer driver

Below is my code:
package mypackage;
import java.io.File;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
public class myclass {
public static WebDriver driver;
public static File file;
public static void main (String[] args){
// declaration and instantiation of objects/variables
file = new File("C:\\DATA\\IEDriverServer_x64_2.42.0\\IEDriverServer.exe");
System.setProperty("webdriver.ie.driver", file.getAbsolutePath());
driver = new InternetExplorerDriver();
String baseURL = "http://www.google.com";
String expectedTitle = "Google";
String actualTitle = "";
// launch IE and direct it to the Base URL
driver.get(baseURL);
// get the actual value of the title
actualTitle = driver.getTitle();
/*
* compare the actual title of the page witht the expected one and print
* the result as "Passed" or "Failed"
*/
if (actualTitle.contentEquals(expectedTitle)){
System.out.println("Test Passed!");
} else {
System.out.println("Test Failed");
}
//close Firefox
driver.close();
// exit the program explicitly
System.exit(0);
}
}
When I run this I get the following exception.
Started InternetExplorerDriver server (64-bit)
2.42.0.0
Listening on port 42229
Exception in thread "main" java.lang.NullPointerException
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:600)
at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:241)
at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:226)
at org.openqa.selenium.ie.InternetExplorerDriver.run(InternetExplorerDriver.java:182)
at org.openqa.selenium.ie.InternetExplorerDriver.<init>(InternetExplorerDriver.java:174)
at org.openqa.selenium.ie.InternetExplorerDriver.<init>(InternetExplorerDriver.java:146)
at mypackage.myclass.main(myclass.java:15)
I too have this problem. I have tried both the 32 and 64 bit drivers. I am using IE11 and have followed the Selenium documentation for configuration for IE11 and updated my Windows registry. https://code.google.com/p/selenium/wiki/InternetExplorerDriver#Required_Configuration
Selenium server was just updated to 2.42.2 today to fix this!
https://code.google.com/p/selenium/issues/detail?id=7415
http://docs.seleniumhq.org/download/
Actually I had the same issue with IEDriverServer_x64_3.5.1.exe, but with the old one (IEDriverServer_x64_2.53.0.exe) it has been resolved.
I'm frustrated since i cant use the fresh version (>3.0)

How to use selenium-server-standalone-2.0rc2 while creating script with RC

package com.html;
import com.thoughtworks.selenium.DefaultSelenium;
import com.thoughtworks.selenium.Selenium;
import junit.framework.TestCase;
public class Html5 extends TestCase{`enter code here`
Selenium selenium1;
public void setUp()
{
selenium1=new DefaultSelenium("localhost",4444,"*firefox","http://live.com");
selenium1.start();
}
}
Error appearing in com.thoughtworks.selenium.DefaultSelenium; and DefaultSelenium("localhost",4444,"*firefox","http://live.com"); line.
Please suggest.
First :
What the enter code here string does there ?
Secondly :
If there is an error in the import com.thoughtworks.selenium.DefaultSelenium; and in the new DefaultSelenium, it's certainly that the jars are not in your classpath
selenium-server-standalone contains the Selenium server classes, but not the client ones, where DefaultSelenium is. You'll have to bring the client jars in your classpath, that is selenium2-java for this version I think
I think you need to give Path to firefox.exe in your Constructor..So
selenium1 = new DefaultSelenium("localhost",4444,"*firefox","http://live.com"); Goes like
selenium1 = new DefaultSelenium("localhost",4444,"*firefox C:\Documents and Settings\Mozilla Firefox\firefox.exe","http://live.com");
Try this once.