c# - 当只需要一个时,Selenium Chromedriver 正在创建多个实例
问题描述
如果我遇到幼稚的问题,我深表歉意,我是 Selenium 的新手,还在学习。
我们正在尝试通过 IIS 在指定机器上运行这些 selenium 测试。
当我在本地运行代码时,一切正常。当我将它发布到我们的机器上时,只有运行一次的任务管理器中会出现两个 chromedriver 实例。有时它会关闭其中一个实例,而其他时候它也不会关闭。有时它甚至会关闭两个实例并正常工作。我不明白为什么它如此不一致。
这是启动代码后任务管理器的屏幕截图。
欢迎对此提出任何建议,以下是我正在运行的代码。
private IWebDriver _driver;
[Route("/Test_SignIn")]
public IActionResult Test_SignIn(string environment = "development")
{
string response = "Failed";
try
{
string outPutDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
_driver = new ChromeDriver(outPutDirectory);
if (environment == "production")
{
_driver.Navigate().GoToUrl(productionUrl);
}
else
{
_driver.Navigate().GoToUrl(developmentUrl);
}
By userNameFieldLocator = By.Id("AccountUserName");
WebDriverWait wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(30));
wait.Until(ExpectedConditions.ElementIsVisible(userNameFieldLocator));
_waitForLoaderToFinish();
IWebElement userNameField = _driver.FindElement(userNameFieldLocator);
IWebElement passwordField = _driver.FindElement(By.Id("AccountPassword"));
IWebElement signInButton = _driver.FindElement(By.XPath("//button[contains(text(), 'Sign In')]"));
userNameField.SendKeys(_username);
passwordField.SendKeys(_password);
signInButton.Click();
By dashboardLocator = By.Id("portalBanner_EmployeeName");
wait.Until(ExpectedConditions.ElementIsVisible(dashboardLocator));
IWebElement dashboard = _driver.FindElement(dashboardLocator);
response = "Success";
}
catch (Exception ex)
{
response = ex.Message;
}
_driver.Close();
_driver.Quit();
return Json(response);
}
private string _waitForLoaderToFinish()
{
try
{
new WebDriverWait(_driver, TimeSpan.FromSeconds(30)).Until(ExpectedConditions.InvisibilityOfElementLocated(By.Id("loader-wrapper")));
return null;
}
catch (TimeoutException e)
{
return $"{e.Message}";
}
}
解决方案
ChromeDriver(和所有其他 Web 驱动程序)是 .NET 中的“一次性”对象。他们实现了IDisposable 接口。实现此接口的对象需要特殊处理才能在完成后进行清理。通常,您会看到这些对象在一个using(...)
块中初始化,如下所示:
using (IWebDriver driver = new ChromeDriver(...))
{
// Use driver
}
参考:C# Using 语句。
我看到您正在关闭并退出浏览器,但您也需要调用_driver.Dispose();
。在您的代码中完成此操作的快速简便的方法是在调用 Quit() 后调用 Dispose():
_driver.Close();
_driver.Quit();
_driver.Dispose(); // <-- this kills Chrome.exe
return Json(response);
或者修改方法以将使用包装_driver
在一个using(...)
语句中:
[Route("/Test_SignIn")]
public IActionResult Test_SignIn(string environment = "development")
{
string response = "Failed";
try
{
string outPutDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
// Your web driver is a LOCAL variable now, beware!
using (IWebDriver driver = new ChromeDriver(outPutDirectory))
{
if (environment == "production")
{
driver.Navigate().GoToUrl(productionUrl);
}
else
{
driver.Navigate().GoToUrl(developmentUrl);
}
By userNameFieldLocator = By.Id("AccountUserName");
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
wait.Until(ExpectedConditions.ElementIsVisible(userNameFieldLocator));
_waitForLoaderToFinish();
IWebElement userNameField = driver.FindElement(userNameFieldLocator);
IWebElement passwordField = driver.FindElement(By.Id("AccountPassword"));
IWebElement signInButton = driver.FindElement(By.XPath("//button[contains(text(), 'Sign In')]"));
userNameField.SendKeys(_username);
passwordField.SendKeys(_password);
signInButton.Click();
By dashboardLocator = By.Id("portalBanner_EmployeeName");
wait.Until(ExpectedConditions.ElementIsVisible(dashboardLocator));
IWebElement dashboard = driver.FindElement(dashboardLocator);
response = "Success";
}
}
catch (Exception ex)
{
response = ex.Message;
}
return Json(response);
}
请注意,您的网络驱动程序现在变成了一个局部变量。它不应该是类上的字段,以防止其他方法访问此一次性资源。
推荐阅读
- ios - 在 Iphone10 下的 IOS 设备上,Material UI 的 IconButton 菜单不显示,如何解决?
- python - 在 Windows10 中运行 pip 的测试不起作用
- dart - 仅运行 Flutter 桌面应用程序的单个实例
- flutter - Flutter http Post- 状态码:401。我可以用 Postman 得到结果。我无法从使用 http 包发布的帖子中获得结果
- python - sqlalchemy (vesrion 1.4 !) - 获取最后插入的 id
- javascript - 如何防止 Css 应用于其他文件?
- c++ - 读取文件中的字符数和单词数
- c++ - 访问存储在变量引用的类对象中的变量
- intellij-idea - 如何在运行/调试配置中为 Intellij 中的 junit 配置和执行多个标签
- javascript - 通过单击更改复选框状态但不工作