[英]Selenium and TestNg parallel run is not attaching driver to every browser that we launched even though i used ThreadLocal concept
I used below code to get parallel run work but unfortunately it is NOT working, can anyone help me on this. 我使用下面的代码来获取并行运行的工作,但不幸的是,它无法正常工作,任何人都可以帮我解决这个问题。
public EmergyaWebDriver initialize() {
log.info("[log-Properties] " + this.getClass().getName() + "- Start initialize test");
tmpDriver = new ThreadLocal<RemoteWebDriver>();
// EmergyaWebDriver tmpDriver = null;
// Driver initialization
if (browser.equalsIgnoreCase("Firefox")) {
FirefoxProfile firefoxProfile = new FirefoxProfile();
firefoxProfile.setPreference("browser.download.manager.focusWhenStarting", true);
firefoxProfile.setEnableNativeEvents(true);
firefoxProfile.setPreference("browser.download.folderList", 2);
firefoxProfile.setPreference("browser.download.manager.showWhenStarting", false);
firefoxProfile.setPreference("browser.download.dir", this.getDownloadPath());
File dir = new File(this.getDownloadPath());
if (dir.isDirectory()) {
File[] files = dir.listFiles();
for (File file : files) {
if (file.isFile()) {
file.delete();
}
}
}
String mimeTypes = getMimeTypes();
// adding mimetypes
firefoxProfile.setPreference("browser.helperApps.neverAsk.saveToDisk", mimeTypes);
// forcing the downloads
firefoxProfile.setPreference("browser.helperApps.neverAsk.openFile", mimeTypes);
firefoxProfile.setPreference("browser.helperApps.alwaysAsk.force", false);
firefoxProfile.setPreference("pdfjs.disabled", true);
// EmergyaFirefoxDriver tmpDriver = new firefoxProfile(firefoxProfile);
DriverManager manager = new DriverManager();
manager.setWebDriver(driver = new EmergyaFirefoxDriver(firefoxProfile));
}
}
public class DriverManager {
private static ThreadLocal<EmergyaWebDriver> EmergyaWebDriver = new ThreadLocal<EmergyaWebDriver>();
public static EmergyaWebDriver getDriver() {
return EmergyaWebDriver.get();
}
public void setWebDriver(EmergyaWebDriver driver) {
EmergyaWebDriver.set(driver);
}
}
What I do is I have four separate classes to handle my browsers: 我要做的是,我有四个单独的类来处理我的浏览器:
ChromeDriverFactory: ChromeDriverFactory:
public class ChromeDriverFactory {
public ThreadLocal<WebDriver> driver;
private Set<WebDriver> drivers = Collections.newSetFromMap(new ConcurrentHashMap<>());
public ChromeDriverFactory(Boolean isHeadless) throws IOException
{
System.setProperty("webdriver.chrome.driver", TestUtils.getRelativePath() + "/externalLibraries/browsers/chromedriver");
System.setProperty("java.awt.headless", Boolean.toString(isHeadless));
DesiredCapabilities caps = DesiredCapabilities.chrome();
caps.setJavascriptEnabled(true);
caps.setCapability("takesScreenshot", true);
ChromeOptions options = new ChromeOptions();
if (isHeadless)
{
options.addArguments("headless");
options.addArguments("disable-gpu");
//options.addArguments("no-sandbox");
}
options.addArguments("disable-extensions");
caps.setCapability(ChromeOptions.CAPABILITY, options);
driver = new InheritableThreadLocal<WebDriver>(){
@Override
protected ChromeDriver initialValue() {
ChromeDriver chromeDriver = new ChromeDriver(caps);
drivers.add(chromeDriver);
return chromeDriver;
}
};
}
}
LocalDriverFactory: LocalDriverFactory:
public class LocalDriverFactory {
public static WebDriver createInstance(String browserName, Boolean isHeadless) throws IOException {
WebDriver driver = null;
if (browserName.toLowerCase().contains("firefox")) {
}
if (browserName.toLowerCase().contains("internet")) {
/*driver = new InternetExplorerDriver();
return driver;*/
}
if (browserName.toLowerCase().contains("chrome")) {
ChromeDriverFactory cFac = new ChromeDriverFactory(isHeadless);
driver = cFac.driver.get();
}
if (browserName.toLowerCase().trim().equals("safari"))
{
/* driver = SafariDriverFactory.driver.get();
LocalDriverManager.setFFWebDriver(driver);*/
}
if (browserName.toLowerCase().trim().contains("phantom"))
{
java.util.logging.Logger.getLogger("com.gargoylesoftware").setLevel(Level.OFF);
}
return driver;
}
}
And LocalDriverManager: 和LocalDriverManager:
public class LocalDriverManager { 公共类LocalDriverManager {
private static ThreadLocal<WebDriver> driver = new ThreadLocal<WebDriver>();
public static WebDriver getDriver() {
return driver.get();
/*driver = chromeWebDriver.get();
if (driver == null)
{
driver = ffWebDriver.get();
}
*/
}
public static void setDriver(WebDriver indriver)
{
driver.set(indriver);
}
} }
Then you have to create a listener like so: 然后,您必须像这样创建一个侦听器:
public class WebDriverListener implements IInvokedMethodListener {
public static int testNumber = 0;
@Override
public void beforeInvocation(IInvokedMethod method, ITestResult testResult){
try
{
LocalTestManager.initializeSettings();
}
catch (IOException e)
{
e.printStackTrace();
}
if (method.toString().toLowerCase().contains("beforescenario")) {
WebDriver driver = null;
try {
driver = LocalDriverFactory.createInstance(TestSettings.getBrowser(), TestSettings.getIsHeadless());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
LocalDriverManager.setDriver(driver);
testNumber ++;
System.out.println("Now executing test number: " + testNumber);
LocalTestManager.setTestName(method.getTestMethod().getMethodName());
}
}
@Override
public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
WebDriver driver = LocalDriverManager.getDriver();
if(method.toString().toLowerCase().contains("afterscenario")){
try {
if (driver != null) {
driver.quit();
}
} catch (Exception e) {
driver.quit();
throw e;
}
finally {
driver.quit();
}
}
}
}
Your tests should call the listener in an xml file like so: 您的测试应在xml文件中调用侦听器,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" thread-count="4" parallel="methods">
<listeners>
<listener class-name="[PATH TO THE WebDriverListener CLASS SEPARATED BY .]WebDriverListener"/>
</listeners>
<test name="Regression">
<classes>
<class name="[PATH TO THE TEST CLASS SEPARATED BY .]SomeTestClass"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
Then you run that xml file through testng. 然后,您通过testng运行该xml文件。 This works for me.
这对我有用。 It opens 4 browsers and executes 4 separate test methods at one time in those 4 browser instances.
它会打开4个浏览器,并在这4个浏览器实例中一次执行4个单独的测试方法。
Note: You have to make sure that you have absolutely NO global static variables. 注意:您必须确保绝对没有全局静态变量。 Everything has to be thread safe (like your browser instances).
一切都必须是线程安全的(例如您的浏览器实例)。
@Trinadh Kumar in regard to your "WebDriverException thrown by findElement(By.xpath: //img[@pc-id = 'logo-big']) org.openqa.selenium.NoSuchSessionException: no such session " error that is occurring. @Trinadh Kumar关于您的“ findElement(By.xpath:// img [@ pc-id ='logo-big'])引发的WebDriverException” org.openqa.selenium.NoSuchSessionException:没有此类会话发生。 Sometimes this happens when you have an outdated version of Chromedriver.
有时,当您使用过时的Chromedriver版本时会发生这种情况。 Try downloading and using the most updated version from https://sites.google.com/a/chromium.org/chromedriver/ .
尝试从https://sites.google.com/a/chromium.org/chromedriver/下载并使用最新版本。 Latest version is 2.30.
最新版本是2.30。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.