问题描述
我正在尝试一种非常罕见的行为,尝试从特定服务中的帐户登录/退出。
具体问题与“--headless”选项有关,没有它它也能正常工作。工作流程如下:
- 访问登录页面,输入电子邮件和密码,然后单击“进入”按钮
- 等待主屏幕加载
- 进入主屏幕后,查找“登录”或“注销”按钮
- 单击上一点中找到的按钮并检查该按钮是否真的被修改(“登录”应更改为“注销”,反之亦然)。这是真正知道操作已执行的确认。
让我发疯的是我在程序执行过程中看不到任何错误,在两种情况下(有和没有 --headless 选项)我的日志显示完全相同的数据(检查底部的代码)。例如对于“注销”请求:
- 2021-02-24 10:42:18.358 [main] 信息 - 正在加载网络...
- 2021-02-24 10:42:20.286 [main] INFO - 网页加载
- 2021-02-24 10:42:20.286 [main] INFO - 等待主屏幕
- 2021-02-24 10:42:22.557 [main] INFO - 检测到进度条
- 2021-02-24 10:42:24.585 [main] INFO - 注销请求
- 2021-02-24 10:42:24.705 [main] INFO - 注销完成
- 2021-02-24 10:42:25.281 [main] INFO - [END] 登录/退出请求已完成
在这两种情况下一切似乎都很顺利,但是在使用 --headless 运行此代码后,如果我手动访问我的帐户,我可以看到我没有注销。但是,如果没有 --headless,它就可以正常工作。
我在开始时使用了多个 ChromeOptions,但它们都不起作用,我检测到将“注销”按钮修改为“登录”按钮对我来说没有意义,但操作没有真的发生了。
这是我正在使用的:
- Chromedriver 88
- Java 1.8
- Java 硒 3.141.59
完整代码如下:
public void run() {
try {
int actionToDo = -1;
log.info("[START] New in/out request for user " + username);
// Webdriver configuration
Map<String,Object> prefs = new HashMap<String,Object>();
prefs.put("geolocation",true);
ChromeOptions options = new ChromeOptions();
options.setExperimentalOption("prefs",prefs);
options.addArguments("--headless");
options.addArguments("--disable-gpu");
options.addArguments("--disable-extensions");
options.addArguments("--start-maximized");
options.addArguments("--headless");
options.addArguments("no-sandbox");
System.setProperty("webdriver.chrome.driver",WoffuUtils.WEBDRIVER_PATH);
WebDriver driver = new ChromeDriver(options);
// Waiting times
driver.manage().timeouts().pageLoadTimeout(GENERAL_WAITING_TIME,TimeUnit.SECONDS);
WebDriverWait wait = new WebDriverWait(driver,GENERAL_WAITING_TIME);
log.info("loading web...");
driver.get(WoffuUtils.URL);
log.info("web loaded");
// Log in
log.info("waiting for the home screen");
WebElement emailInput = driver.findElement(By.id("tuEmail"));
WebElement passwordInput = driver.findElement(By.id("tuPassword"));
emailInput.sendKeys(username);
passwordInput.sendKeys(password);
driver.findElement(By.xpath("//*[@id=\"intro\"]/div/form/span/button")).click();
// Wait until the home page is loaded
wait.until(myDriver -> driver.findElement(By.className("progress-bar")));
log.info("progress bar detected");
// Identify if we shoud login in or log out
WebElement inOutButton = null;
// Introduce a short sleep time because the home screen seems to show the "In" button
// always even when you are already logged in. The "in" is properly replaced by the
// "out" button almost immediately but without this short waiting time the action is
// always detected as "Log in"
Thread.sleep(HOME_SCREEN_SLEEP_TIME_MILLIS);
try {
inOutButton = driver.findElement(By.id("in"));
actionToDo = WoffuUtils.ACTION_LOG_IN;
log.info("Log in request");
} catch (NoSuchElementException noElementExcIn) {
try {
inOutButton = driver.findElement(By.id("out"));
actionToDo = WoffuUtils.ACTION_LOG_OUT;
log.info("Log out request");
} catch (NoSuchElementException noElementExcOut) { }
}
// Perform the final click on the appropriate button
switch (actionToDo) {
case WoffuUtils.ACTION_LOG_IN:
inOutButton.click();
wait.until(myDriver -> driver.findElement(By.id("out")));
log.info("Log in DONE");
break;
case WoffuUtils.ACTION_LOG_OUT:
inOutButton.click();
wait.until(myDriver -> driver.findElement(By.id("in")));
log.info("Log out DONE");
break;
default:
log.error("ERROR: LOG IN/OUT BUTTON NOT DETECTED !!!");
}
driver.quit();
log.info("[END] Log in/out request finished");
} catch (Exception e) {
log.error("ERROR in Selenium in/out handler: " + e.getMessage());
} finally {
// Remove the request from the pending list
String requestToRemove = this.username + WoffuUtils.REQUEST_SEPARATOR + this.password;
WoffuUtils.pendingRequests.remove(requestToRemove);
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)