集成信息系统的End-2-End测试自动化
第2-2部分。实现使用浏览器将文件从容器上传到测试框架的过程。搜索浏览器下载的文件的名称
作者:habr.com/us/users/anrad
集线器:
标签:#autotest,#selenium,#selenoid,#headlessbrowser,#download在为UI开发End-2-End自动测试时,我们面临着“如何获取最后加载的名称”的问题。文件从WebDriver中下载?”,Google并没有很快得到任何信息。因此,我写了这篇文章,同时讲述了我们究竟遇到了什么问题以及如何解决它。通过本文,我们将继续发表一系列出版物,介绍如何在一个大型LANIT项目中自动化大型信息系统(以下称为“系统”)的手动测试(以下称为“自动测试”)过程以及该过程的结果。
资源本文本身完成了该周期,下面是到前面所有部分的链接:第1部分。组织和管理。为什么我们需要自动化。组织开发和管理过程。使用的组织第2部分。技术。体系结构和技术堆栈。实施细节和技术惊奇部分2-1。一年前,所有测试和JUnit RuleChain的基类实现。因此,今天可能不相关。如果您知道使用多台Selenoid网格服务器处理文件的有效方法,请在注释中写上。在开发“自动测试”时,我们的任务是从系统中下载(下载)文件并随后对其内容进行分析。要从经过测试的系统“上传”文件,我们使用以下解决方案:- 对于“本地”启动模式(直接在工作PC上启动)-初始化“本地”浏览器时,会将临时本地文件夹的名称作为参数传递给它。接下来,直接从本地文件夹读取文件以进行后续分析;
- 对于“远程”模式(通过Bamboo)-文件是通过电磁阀服务器功能通过浏览器从容器中“获取”的:selenoid-host.example.com:4444 /下载/ {SESSION_ID} / {FILE_NAME}
详细信息在文档中描述。对于这两种模式,要访问文件,您都必须知道其名称。这真是一个惊喜。“下载”文件的名称上缺少数据的问题如下:- “单击”“下载文件”按钮后,浏览器将文件下载到容器中相应的本地文件夹中;
- 在这种情况下,文件名是动态形成的,因此,如何提前确定它,我们找不到。这是我们测试系统的功能;
- 此外,应从容器中“拉出”该文件,并对其内容进行商业验证;
- 为了“拉出”文件,您应该知道其名称,但是我们不知道名称,因为名称是动态生成的,并且链接中没有值。
此外,由于某些测试的复杂性,使得测试期间可能会卸载多个文件,这些文件作为测试本身组成的不同独立测试脚本的一部分而加剧了这种情况。对我们来说最好的解决方案是确定最后下载文件的方法。有几种方法可以做到这一点:- . . , ;
- Google Chrome javascript chrome://downloads/, html-. .
对于本地模式,分析浏览器加载的文件的组成是一项艰巨的任务。对于远程模式,您需要使用服务器selenoid的“未记录”功能:selenoid-host.example.com:4444 / download / {SESSION_ID}显示所有成功下载的文件的列表,其中SESSION_ID是Selenoid会话ID。通常,该方案可以正常工作,但有一个例外:您需要等待一段时间,直到文件下载并出现在列表中。可以通过超时周期设置等待时间,但是,这样我们就无法获取有关可能的文件上传错误的信息。我们只能确定文件未在此电路中加载。因此,最后,我们确定了通过chrome确定文件名的方法://下载/页面。通过chrome获取文件名://下载/页
此方法在本地和远程模式下均能很好地工作。工作方案非常简单:- 运行Java脚本以打开chrome窗口://下载/;
- 以常规方式在窗口中处理数据。等待直到列表中的第一个文件被加载并确定其名称;
- 关闭镶边://下载/窗口并返回您要查找的文件的名称。
我们在谷歌上搜索了使用chrome的想法://下载/,但遗憾的是,我没有提供到源的链接,因为它没有被保留。下面给出了用于获取文件名的类的实际实现。用于通过chrome获取下载文件名称的类://下载/ private static final long DOWNLOADS_PAGE_LOAD_TIMEOUT = 5_000;
private static final long MAX_GET_FILE_NAME_ATTEMPT = 5;
public static String getLastDownloadedFilename() throws DownloaderException {
String[] filename = new String[1];
Exception[] ex = new Exception[1];
WebDriver driver = WebDriverRunner.getWebDriver();
JavascriptExecutor executor = (JavascriptExecutor) driver;
Utils.driver.openNewTabCheckAndClose(
() -> {
executor.executeScript("window.open('','_blank');");
},
() -> {
driver.get("chrome://downloads/");
for (int i = 0; i < MAX_GET_FILE_NAME_ATTEMPT; i++) {
ex[0] = null;
sleep();
try {
WebElement element = (WebElement) executor.executeScript(
"return document.querySelector('downloads-manager').shadowRoot.querySelector('downloads-item').shadowRoot.getElementById('file-link')");
filename[0] = element.getText();
LOGGER.info("Attempt get file name " + i + ". Name = '" + filename[0] + "'");
} catch (WebDriverException e) {
ex[0] = e;
LOGGER.info("Failed attempt "+ i + " to get filename text: " + e.getMessage());
continue;
}
if (filename[0] != null && !filename[0].isEmpty()) {
executor.executeScript(
"document.querySelector('downloads-manager').shadowRoot.querySelector('downloads-item').shadowRoot.getElementById('remove').click()");
break;
}
}
}
);
if (filename[0] != null && !filename[0].isEmpty()) {
return filename[0];
}
String message = "Timeout. Can not get last downloaded file name from chrome://downloads/. File name is '" + filename[0] + "'. Exception: " + ex[0].getMessage();
LOGGER.warning(message);
throw new DownloaderException(message, ex[0]);
}