lunes, 25 de octubre de 2021

Selenium (3): Install in a server without GUI : Chrome & Gecko

1. New Post

Now you don't need to install Firefox or Chrome in a Linux Server without GUI, you only need to copy the drivers from
  • https://github.com/mozilla/geckodriver/releases for Gecko (Firefox) or
  • https://chromedriver.chromium.org/downloads for Chrome
And you have to set options to "headless"

Here is the code of a class to use headless chrome and gecko that works in an ubuntu server

package ximodante.basic.utils.selenium;

import java.io.File;
import java.io.IOException;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.Point;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.firefox.FirefoxProfile;
//import org.openqa.selenium.htmlunit.HtmlUnitDriver;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;

/**
 * IMPORTANT: You must have downloaded CHROME-DRIVER OR FIREFOX-DRIVER(Gecko Driver) and installed in your system
 * DOWNLOAD from:
 *  https://chromedriver.chromium.org/downloads
 *  https://github.com/mozilla/geckodriver/releases/
 * 
 * @author ximo dante
 *
 */
public class SeleniumEduImp implements ISeleniumEdu{
	private String driverName="webdriver.chrome.driver";
	private String browserPath="/home/informatica/MyPrograms/Selenium/chromedriver";
	private Integer left=1; 
	private Integer top=1; 
	private Integer width=300; 
	private Integer height=200; 
	private String[] opts=null; 
	private Long implicitWait=10L; 
	private String downloadDir="/home/informatica/downloads";
	private Integer timeout=10;
	private Integer cycleTimeout=10;
	
	private Wait<WebDriver> fluentWait=null;
	private WebDriver webDriver=null;
	private WebElement webElement=null;
	
	
	public SeleniumEduImp(String driverName, String browserPath, 
			Integer left, Integer top, Integer width, Integer height, String[] opts, 
			Long implicitWait, String downloadDir, Integer timeout, Integer cycleTimeout) {
		if (driverName  !=null) this.driverName = driverName;
		if (browserPath !=null) this.browserPath =browserPath;
		if (left        !=null) this.left=        left;
		if (top         !=null) this.top=         top;
		if (width       !=null) this.width=       width;
		if (height      !=null) this.height=      height;
		if (opts        !=null) this.opts=        opts;
		if (implicitWait!=null) this.implicitWait=implicitWait;
		if (downloadDir !=null) this.downloadDir= downloadDir;
		
		if (timeout     !=null) this.timeout=     timeout;
		if (cycleTimeout!=null) this.cycleTimeout=cycleTimeout;
		
		this.webDriver=getWebdriver(this.driverName, this.browserPath,
				this.left, this.top, this.width, this.height, 
				this.opts, this.implicitWait, this.downloadDir);
		//this.fluentWait=getFluentwait(this.webDriver, this.timeout, this.cycleTimeout);
		
	}
	
	
	
	private Wait<WebDriver> getFluentwait(WebDriver driver, int timeout, int cycleTimeout) {
		return new FluentWait<WebDriver>(driver)       
	   		.withTimeout(Duration.ofSeconds(timeout))
		.pollingEvery(Duration.ofSeconds(cycleTimeout))    
		.ignoring(NoSuchElementException.class); 
	}
	
	
	private WebDriver getWebdriver(String driverName, String browserPath, 
			Integer left, Integer top, Integer width, Integer height, String[] opts, 
			Long implicitWait, String downloadDir) {
		System.setProperty(driverName, browserPath);
				
		WebDriver driver =null;
		if (driverName.contains(".chrome.")) {
			ChromeOptions options=new ChromeOptions();
			if (opts!=null) options.addArguments(opts);
			//options.addArguments("--headless", "--disable-gpu", "--window-size=1920,1200","--ignore-certificate-errors", "--silent");
			if (downloadDir!=null) {
				if (downloadDir.trim().length()>0) {
					Map<String, Object> prefs = new HashMap<String, Object>();
					prefs.put("download.default_directory",  downloadDir);
					prefs.put("download.prompt_for_download" ,false);
					prefs.put("download.directory_upgrade", true);
					prefs.put("download.safebrowsing.enabled", true);
					prefs.put("useAutomationExtension", false); //Headless only!!!
					options.setExperimentalOption("prefs", prefs);
					
				}
			}
			driver = new ChromeDriver(options);
		}
		else if (driverName.contains(".gecko.")) {
			FirefoxOptions options=new FirefoxOptions();
			
			FirefoxProfile profile = new FirefoxProfile();
			profile.setPreference("browser.download.folderList",2);
			profile.setPreference("browser.download.dir", downloadDir);
			profile.setPreference("browser.helperApps.neverAsk.saveToDisk", "text/csv,application/zip,application/pdf");
						
			options.setProfile(profile);
			if (opts!=null) options.addArguments(opts);
			//options.addArguments("--headless", "--disable-gpu", "--window-size=1920,1200","--ignore-certificate-errors", "--silent");
			driver = new FirefoxDriver(options);
			
			
		}
		if (width>100 && height>100) driver.manage().window().setSize(new Dimension(width,height));
		if (top>=0 && left>=0) driver.manage().window().setPosition(new Point(left, top));
	    
	    driver.manage().deleteAllCookies();
	    if (implicitWait>0) driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(implicitWait)); //????
	    return driver;
	}
	
	//============================================================================
	//Public 
	
	/**
	 * Quit the browser
	 */
	@Override
	public boolean quit() {
		//this.webDriver.quit();
		try {this.webDriver.close();}catch (Exception e) {e.printStackTrace();}
		try {this.fluentWait=null;}catch (Exception e) {e.printStackTrace();}
		try {this.webDriver.quit();}catch (Exception e) {e.printStackTrace();}
		return true;
	}
	
	@Override
	public boolean isSessionNull() {
		return this.webDriver==null;
	}
	
	/**
	 * Go to a web page
	 */
	@Override
	public void gotoURL(String url) {
		this.webDriver.get(url);
		this.fluentWait=getFluentwait(this.webDriver, this.timeout, this.cycleTimeout);
	}
	/**
	 * Find a web element by xpath
	 * @param xpath
	 * @return
	 */
	@Override
	public boolean findElementByXpath(String xpath) {
		boolean found=false;
		try {
			this.webElement=this.webDriver.findElement(By.xpath(xpath));
			if (this.webElement!=null) found=true;
		} catch (Exception e) {
			System.out.println ("No trobat "+ xpath);
		}	
		return found;
	}
	
	@Override
	public boolean findElementById(String id) {
		boolean found=false;
		try {
			this.webElement=this.webDriver.findElement(By.id(id));
			if (this.webElement!=null) found=true;
		} catch (Exception e) {
			System.out.println ("No trobat "+ id);
		}	
		return found;
	}
	
	/**
	 * click the component
	 */
	@Override
	public void elementClick() {
		this.webElement.click();
	}
	
	/**
	 * Reset the content of the component
	 */
	@Override
	public void elementClear() {
		this.webElement.clear();
	}
	
	/**
	 * Send keys to the component
	 * @param keysToSend
	 */
	@Override
	public void elementSendKeys(CharSequence... keysToSend) {
		this.webElement.sendKeys(keysToSend);
	}
	
	/**
	 * Return the text of the control (if not hidden)
	 * @return
	 */
	@Override
	public String getElementText() {
		return this.webElement.getText();
	}
	
	
	@Override
	public boolean clickByXpath(String xpath) {
		boolean found=false;
		this.webElement=this.webDriver.findElement(By.xpath(xpath));
		if (this.webElement!=null) found=true;
		this.webElement.click();
		return found;
	}
	
	@Override
	public boolean elementSendKeysByXpath(String xpath, CharSequence... keysToSend) {
		boolean found=false;
		this.webElement=this.webDriver.findElement(By.xpath(xpath));
		if (this.webElement!=null) found=true;
		this.webElement.sendKeys(keysToSend);
		return found;
	}
	
	@Override
	public String getElementTextByXpath(String xpath) {
		this.webElement=this.webDriver.findElement(By.xpath(xpath));
		return this.webElement.getText();
	}
	
	@Override
	public String getCurrentUrl() {
		return this.webDriver.getCurrentUrl();
	}
	
	@Override
	public String getAttribute(String attributerName) {
		return this.webElement.getAttribute(attributerName);
	}
	
	@Override
	public String getPageCode() {
		return this.webDriver.getPageSource();
	}
	
	@Override
	public void saveScreenShot(String fileName) throws IOException {
		TakesScreenshot scrShot =(TakesScreenshot) this.webDriver;
		File SrcFile=scrShot.getScreenshotAs(OutputType.FILE);
		File DestFile=new File(fileName);
		FileUtils.copyFile(SrcFile, DestFile);
	}
	
	@Override
	public void close() {
		this.webDriver.close();
	}
	
	public static void main (String[] args) {
		var selenium=new SeleniumEduImp(
				"webdriver.chrome.driver",
				"/home/informatica/MyPrograms/Selenium/chromedriver", 
				0, //left),
				0, //top
				100, //width
				800, //height
				new String[]{
						"--headless",
						"user-agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
				}, //Opts null,
				//new String[]{"headless"}, //Opts null,
				//null, // quitar
				10L,
				"/home/informatica/MyResources",
				20,
				null
				);
		
		boolean ok=false;
		boolean found=false;
		int maxTries=5;
		int nTries=0;
		
		selenium.gotoURL("http://localhost:8080/W01-CSV/provaservlet");
		
	}
	
		
}

 

================================================

2. OLD Post Don't use it!

 1. Install xvfb

1
2
3
4
5
6
7
8
#install Xvfb
sudo apt-get install xvfb

#set display number to :5
Xvfb :1 -screen 5 1024x768x8 &
export DISPLAY=:1.5    

#you are now having an X display by Xvfb


2. Install chrome


 wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.debwget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb

 sudo dpkg -i google-chrome-stable_current_amd64.deb

Gives an error (because expects the system to have a GUI) . But you must check the version in the log

in my case it is 95.0.4638.47+


3. Download the chromedriver

in 

https://chromedriver.chromium.org/downloads 

select the desired version in this case 95.0.4638.17

download it in a directory that will be referenced by the java software!!!


4. What else

Now from the java program, the references to the chromedriver should be to the new server, and follow the steps of the last posts.

No hay comentarios:

Publicar un comentario