I have been working on this automation project for 2 years and now I am trying to implement parallel testing with ThreadLocal. I have done a lot of research on this and I have implemented ThreadLocal driver = new ThreadLocal<>(); in my BaseTestClass. My problem is I am using the page object model where each page is a class with objects. Eclipse is saying change constructor to
public LoginLogoutPage(ThreadLocal<WebDriver> driver) {
this.driver = driver;
}
I do that then I am prompted to change WebDriver driver; to ThreadLocal driver. After I do that all my fluent wait have a red line under them saying
"The constructor FluentWait<WebDriver>(ThreadLocal<WebDriver>) is undefined"
However I do not know how to fix this. Here is a snippet below.
public class BaseTestCriticalScenarios {
protected static ThreadLocal<WebDriver> driver = new ThreadLocal<>();
#BeforeClass
public void setUp() throws InterruptedException, MalformedURLException {
// --------Extent Report--------
report = ExtentManager.getInstance();
// -----------------------------
System.setProperty("webdriver.chrome.driver", "C:\\GRID\\chromedriver.exe");
ChromeOptions option = new ChromeOptions();
// --https://stackoverflow.com/questions/43143014/chrome-is-being-controlled-by-automated-test-software
option.setExperimentalOption("useAutomationExtension", false);
option.setExperimentalOption("excludeSwitches", Collections.singletonList("enable-automation"));
// --https://stackoverflow.com/questions/56311000/how-can-i-disable-save-password-popup-in-selenium
option.addArguments("--disable-features=VizDisplayCompositor");
option.addArguments("--start-maximized");
option.addArguments("--disable-gpu");
Map<String, Object> prefs = new HashMap<String, Object>();
prefs.put("credentials_enable_service", false);
prefs.put("profile.password_manager_enabled", false);
option.setExperimentalOption("prefs", prefs);
System.out.println(System.getenv("BUILD_NUMBER"));
String env = System.getProperty("BUILD_NUMBER");
if (env == null) {
DesiredCapabilities capability = DesiredCapabilities.chrome();
capability.setCapability(CapabilityType.BROWSER_NAME, "Chrome");
capability.setCapability(ChromeOptions.CAPABILITY, option);
option.merge(capability);
driver.set(new RemoteWebDriver(new URL(COMPLETE_NODE_URL), capability));
getDriver().get(HOME_PAGE);
getDriver().manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
} else {
driver.set(new ChromeDriver(option));
getDriver().manage().window().maximize();
getDriver().get(HOME_PAGE);
getDriver().manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
}
public WebDriver getDriver() {
//Get driver from ThreadLocalMap
return driver.get();
}
Below is my page object class
Any help would be appreciated.
Related
Im trying run my TestNG test and I am getting this error:
Cannot inject #Test annotated Method [Test1] with [class io.appium.java_client.android.AndroidDriver].
Dont know what must do. I'm using Appium whit TestNG.
#Listeners(ExtentITestListenerAdapter.class)
public class TestNG {
public AppiumDriver <AndroidElement>driver;
#Test
public void Test1(AndroidDriver driver) {
MobileElement el1 = (MobileElement) driver.findElementById("skip_button");
el1.click();
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
TouchAction touchAction = new TouchAction(driver);
touchAction.tap(new PointOption().withCoordinates(725, 993)).perform();
touchAction.tap(new PointOption().withCoordinates(293, 1005)).perform();
touchAction.tap(new PointOption().withCoordinates(1175, 1531)).perform();
touchAction.tap(new PointOption().withCoordinates(1166, 2029)).perform();
touchAction.tap(new PointOption().withCoordinates(763, 2036)).perform();
MobileElement el2 = (MobileElement) driver.findElementById("continue_button");
el2.click();
}
#BeforeClass
public void setUp() throws MalformedURLException {
DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
desiredCapabilities.setCapability("platformName", "Android");
desiredCapabilities.setCapability("deviceName", "Pixel_4_2");
desiredCapabilities.setCapability("automationName", "UiAutomator2");
desiredCapabilities.setCapability("udid", "emulator-5554");
desiredCapabilities.setCapability("app", "C:\\Users\\Diego\\Desktop\\flow-music-develop-dev-debug-v0.11.0-SNAPSHOT-209.apk");
desiredCapabilities.setCapability("ensureWebviewsHavePages", true);
URL remoteUrl = new URL("http://localhost:4723/wd/hub");
driver = new AndroidDriver(remoteUrl, desiredCapabilities);
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
#After
public void tearDown() {
driver.quit();
}
}
If you want to use parameters in test method, you need to provide the DataProvider or using Parameter from file testng.xml
Link to docs: https://testng.org/doc/documentation-main.html#parameters
In this case, just remove the parameter of method, i.e public void Test1(AndroidDriver driver) -> public void Test1()
I found the solution
#BeforeMethod
public void setUp() throws Exception{
DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
desiredCapabilities.setCapability("platformName", "Android");
desiredCapabilities.setCapability("deviceName", "Pixel_4_2");
desiredCapabilities.setCapability("automationName", "UiAutomator2");
desiredCapabilities.setCapability("udid", "emulator-5554");
desiredCapabilities.setCapability("app", "C:\\Users\\Diego\\Desktop\\flow-music-develop-dev-debug-v0.11.0-SNAPSHOT-209.apk");
desiredCapabilities.setCapability("ensureWebviewsHavePages", true);
URL remoteUrl = new URL("http://localhost:4723/wd/hub");
driver = new AndroidDriver(remoteUrl, desiredCapabilities);
String sessionId = driver.getSessionId().toString();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
I declare this method using the #BeforeMethod, if you seed this method contain this
"driver = new AndroidDriver(remoteUrl, desiredCapabilities);"
Using this i havent the problem.
Ty all
In the below code we are trying to capture the information when the chrome opens the file, but it is failing in some cases as some log files are getting downloaded and it's not viewable in chrome.
Let me know if any preference has to be added so that all files (irrespective of size) can be either viewed or downloaded.
public class DownloadFile {
String FILE_ADD = "file:///";
String LOG_PATH = "path";
String LOG_FILE = "sample.log";
String OUTPUT_FILE = "output.txt";
public static RemoteWebDriver driver;
#BeforeEach
public void setUp() throws Exception {
System.setProperty("webdriver.chrome.driver","chromedriver.exe");
ChromeOptions options = new ChromeOptions();
//Map<String, Object> prefs = new HashMap<String, Object>();
//prefs.put("download.prompt_for_download", false);
//prefs.put("log.disabled", true);
//options.setExperimentalOption("prefs", prefs);
//driver = new ChromeDriver(options);
//driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
//driver.manage().window().maximize();
String fileDownloadPath = "downnloadpath";
Map<String, Object> prefsMap = new HashMap<String, Object>();
prefsMap.put("profile.default_content_settings.popups", 0);
prefsMap.put("download.default_directory", fileDownloadPath);
prefsMap.put("txtjs.disabled", true);
ChromeOptions option = new ChromeOptions();
option.setExperimentalOption("prefs", prefsMap);
option.addArguments("--test-type");
option.addArguments("--disable-extensions");
//Any preference to be added to download all the files instead of viewing some files in chrome
driver = new ChromeDriver(option);
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.manage().window().maximize();
}
#Test
public void fileDownload() throws AWTException, InterruptedException, IOException {
driver.get(FILE_ADD+LOG_PATH+LOG_FILE);
//String output = driver.findElement(By.xpath("/html/body/pre")).getText();
//String final_output = output.replaceAll("User.*>", "testing");
//FileUtils.writeFile(LOG_PATH+OUTPUT_FILE, output);
Thread.sleep(7000);
}
#AfterEach
public void tearDown() throws Exception {
driver.quit();
}
}
To my knowledge, you can not have this custom, where you can set it to view for 1 file, or download for the next, unless you override the ChromeDriver options below you download...
The below is if you wish to download the file/without a dialog box:
download.prompt_for_download is what you should use.
String downloadFilepath = "C:\\DownloadDirectoryPath"
HashMap<String, Object> chromePreferences = new HashMap<String, Object>();
chromePreferences.put("profile.default_content_settings.popups", 0);
chromePreferences.put("download.prompt_for_download", "false");
chromePreferences.put("download.default_directory", downloadFilepath);
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.setExperimentalOption("prefs", chromePreferences);
=== Edited ===
You could try to use the option:
chromePreferences.put("profile.content_settings.exceptions.automatic_downloads.*.setting", 1 );
Are you using setExperimentalOption? What is your ChromeDriver version?
Using: ChromeDriver 91, you can look into your Preferences file under the directory: C:\Users<yourName>\AppData\Local\Google\Chrome\User Data\Default
The below URLs, Chrome does not popup a Download Dialog box.
In my Preferences file, I have the following as an example:
"automatic_downloads": {
"https://folkets-lexikon.csc.kth.se:443,*": {
"last_modified": "13182517278621031",
"setting": 1
},
"https://mail.google.com:443,*": {
"last_modified": "13160578764124505",
"setting": 1
}
},
As a reference, the below are helpful:
Disable chrome download multiple files confirmation
Could not set download.prompt_for_download false for avoiding popup when downloading a file in an Electron application
How to use chrome webdriver in selenium to download files in python?
While using selenium with java, WebdriverManager is not running and the below code is giving null pointer exception. I have returned the driver at end of class.
I have one ask whether should I keep the Webdriver driver as static or not.
import io.github.bonigarcia.wdm.WebDriverManager;
public class Browserselector {
public WebDriver driver;
public static Properties prop;
public WebDriver initializeDriver() throws IOException {
{
String browserName = "firefox";
System.out.println(browserName);
if (browserName.contains("Chrome")) {
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver();
} else if (browserName.contains("IE")) {
WebDriverManager.iedriver().setup();
driver = new InternetExplorerDriver();
} else if (browserName.contains("FireFox")) {
WebDriverManager.firefoxdriver().setup();
driver = new FirefoxDriver();
} else if (browserName.contains("EDGE")) {
WebDriverManager.edgedriver().setup();
driver = new EdgeDriver();
}
}
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().window().maximize();
driver.get("google.com");
return driver;
}
}
Thanks for your help in advance.
you are trying to start "firefox" - but the if condition checks for "Firefox", if you want to use it like that change the following condition
browserName.contains("FireFox")
into
browserName.equalsIgnoreCase("FireFox")
I recommend you to change the nested if with a "switch" it's more readable and easy to follow/understand
Also, don't use a URL without specifying the protocol
driver.get("https://www.google.com");
I'm trying to browse with Selenium using a proxy but it fails and show my public IP instead
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver", "D:\\driverChrome.exe");
ChromeOptions option = new ChromeOptions();
Proxy proxy = new Proxy();
proxy.setHttpProxy("200.111.182.6:443");
option.setCapability(CapabilityType.PROXY, proxy);
WebDriver driver = new ChromeDriver(option);
driver.get("https://whatismyipaddress.com");
driver.manage().window().maximize();
}
As per the Java Docs setCapability() method from MutableCapabilities is defined as:
setCapability
public void setCapability(java.lang.String key, java.lang.Object value)
So instead of setCapability(CapabilityType.PROXY, proxy) you have to use setCapability("proxy", proxy);. So effectively your code block will be:
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver", "D:\\driverChrome.exe");
ChromeOptions option = new ChromeOptions();
Proxy proxy = new Proxy();
proxy.setHttpProxy("200.111.182.6:443");
option.setCapability("proxy", proxy);
WebDriver driver = new ChromeDriver(option);
driver.get("https://whatismyipaddress.com");
driver.manage().window().maximize();
}
tl; dr
Capabilities & ChromeOptions
The following code solved my problem
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver", "D:\\driverChrome.exe");
ChromeOptions option = new ChromeOptions();
option.addArguments("--proxy-server=http://51.38.22.57:8522");
WebDriver driver = new ChromeDriver(option);
driver.get("https://whatismyipaddress.com");
driver.manage().window().maximize();
}
I'm trying to instantiate a single instance of WebDriver to use throughout some tests and, in doing so, I may have over complicated. I think I just need to instantiate a static webdriver and then re-use once for each feature file, assuming that's possible.
I'm not clear why the driver is not being instantiated. I am trying to Debug by running from feature file in the IDE (intelliJ). I'm expecting driver to instantiate when Super is called.
Step Defs:
public class FindAHolidayStepDefs extends DriverBase {
private HolidaysHomePage tcHomePage;
private SearchResultsPage searchPage;
#Before //this is the cucumber #Before
public void setup(){
holHomePage = new HolidaysHomePage(driver);
searchPage = new SearchResultsPage(driver);
}
#Given("^I am on the Holidays homepage$")
public void IAmOnTheHolidaysHomepage() {
assertEquals("the wrong page title was displayed !", "Cheap Travel\u00ae : Cheap Holidays & Last Minute Package Deals", holHomePage.getTitle());
} // more step defs below...
PageObject:
public class HolidaysHomePage extends SeleniumBase {
public HolidaysHomePage(WebDriver driver) {
super(driver); //Expecting driver to instantiate here
visit("");
driver.manage().window().maximize();
assertTrue("The Holidays header logo is not present",
isDisplayed(headerLogo));
}
//code...
DriverBase:
public class DriverBase implements Config {
protected WebDriver driver;
#Before //this is the Junit #Before
public void before() throws Throwable {
if (host.equals("localhost")) {
switch (browser) {
case "firefox":
driver = new FirefoxDriver();
break;
case "chrome":
System.setProperty("webdriver.chrome.driver",
System.getProperty("user.dir") + "\\drivers\\chromedriver.exe");
driver = new ChromeDriver();
break;
}
}
}
#After
public void after() {
driver.quit();
}
};
SeleniumBase (just a class with Selenium API methods abstracted out)
public class SeleniumBase implements Config {
public WebDriver driver;
public SeleniumBase(WebDriver driver) {
this.driver = driver;
}
public void visit(String url) {
if (url.contains("http")) {
driver.get(url);
} else {
driver.get(baseUrl + url);
}
}
Config:
public interface Config {
final String baseUrl = System.getProperty("baseUrl", "http://holidaystest.co.uk/");
final String browser = System.getProperty("browser", "chrome");
final String host = System.getProperty("host", "localhost");
}
Based on your code, here are my suggestions:
You do not need to have a DriverBase class as you already created a SeleniumBase class
Move the below driver initialization code to setup() method in FindAHolidayStepDefs
FindAHolidayStepDefs should extend SeleniumBase
if (host.equals("localhost")) {
switch (browser) {
case "firefox":
driver = new FirefoxDriver();
break;
case "chrome":
System.setProperty("webdriver.chrome.driver",
System.getProperty("user.dir") + "\\drivers\\chromedriver.exe");
driver = new ChromeDriver();
break;
}
}