Selenium 和 Selenide 主要用于 执行浏览器 UI 测试 和自动化浏览器中的工作流程。但有时,我们可能需要创建一个桌面应用程序,通过在浏览器中导航 Web 应用程序来执行某些业务功能。这通常是商业应用程序的常见用例,这些应用程序不提供 API 访问来获取/更新其数据。
Selenide 对于这些应用程序来说是一个极好的选择,它在自动化浏览器工作流程方面表现出色。但在运行时,Selenide 需要存在某些目录才能存储执行期间捕获的输出/截图。
1. 问题
在 Selenide 中,错误 “java.lang.IllegalArgumentException: Failed to create folder” 通常发生在 Selenide 尝试保存截图、页面源代码或日志时,但由于权限问题或不正确的路径而无法创建所需的目录。
默认情况下,在开发环境中(例如 IDE 中),Selenide 使用项目根目录作为基本文件夹,并在其中创建所需的子目录。因此,我们永远不会在开发环境中遇到此问题。
但是,假设我们要 将此实用程序应用程序分发为可安装的应用程序或 exe。当我们安装应用程序时,它通常安装在“c:/program files”中,操作系统不允许出于安全原因在其中创建子目录。因此,当我们启动应用程序时,我们将获得以下 IllegalArgumentException: Failed to create folder 错误。
2025-02-17 15:26:30 com.example.app.processor.BrowserManager ERROR [153] : An error occurred during the workflow execution:
java.lang.IllegalArgumentException: Failed to create folder 'C:\Program Files\myapp\build\downloads\1739786190288_10940_51'
at com.codeborne.selenide.impl.FileHelper.ensureFolderExists(FileHelper.java:48) ~[myapp-1.0.0-jar-with-dependencies.jar:?]
...
...
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) ~[?:?]
at java.util.concurrent.FutureTask.run(Unknown Source) ~[?:?]
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) ~[?:?]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) ~[?:?]
at java.lang.Thread.run(Unknown Source) [?:?]
Caused by: java.nio.file.AccessDeniedException: C:\Program Files\GST IMS Tool\build
at sun.nio.fs.WindowsException.translateToIOException(Unknown Source) ~[?:?]
....
2. 原因
如上所述,**发生错误的原因是操作系统不允许 Selenide 由于安全限制而创建文件夹。**
在开发环境中,通常我们不会在受保护的系统文件夹中工作,因此不会遇到任何问题。但在安装的应用程序中,Selenide 尝试在系统目录中创建文件夹,这不允许,因此会发生此错误。
3. 解决方案
解决方案 1:停止生成执行结果
第一种方法非常简单直接。不要生成所有执行结果,例如报告、日志和屏幕截图。如果未生成输出,则无需创建子目录。
import com.codeborne.selenide.Configuration;
public class TestConfig {
static {
// Disable screenshot capturing
Configuration.screenshots = false;
// Disable saving page source
Configuration.savePageSource = false;
// Prevent storing reports (Windows equivalent of /dev/null is NUL)
Configuration.reportsFolder = "NUL";
}
}
解决方案 2:配置具有写入权限的目录路径
解决此问题的另一种方法是将生成的报告/屏幕截图写入应用程序具有写入权限的目录中。
我们可以配置预先存在的子目录的路径,甚至可以在应用程序代码中创建这些子目录。
// ............. Inside AppConstants.Java
public static final String BASE_DATA_DIR = System.getProperty("user.home") +
File.separator + "AppData" +
File.separator + "Local" +
File.separator + APP_NAME;
// .............. Inside BrowserManager.java
static {
//Setup web driver. Chrome in this case.
createDirectories();
}
private static void createDirectories() {
List<String> requiredDirs = Arrays.asList(
"downloads",
"reports/tests",
"reports/screenshots",
"reports/page-sources",
"chrome_data"
);
requiredDirs.forEach(dir -> {
try {
Files.createDirectories(Paths.get(BASE_DATA_DIR, dir));
} catch (IOException e) {
log.error("Failed to create directory: {}", dir, e);
}
});
}
您可以根据您的需求重构/重新排列上述代码,但整体逻辑保持不变。此代码在应用程序启动时,将在 C:\Users\myUser\AppData\Local\myApp 文件夹中创建必要的依赖项,该文件夹通常具有用于写入应用程序缓存和数据文件的写入权限。
4. 结论
在本篇简短的 Java 教程中,我们讨论了一个在安装的 Java 应用程序中常见的,使用 Selenide 运行基于浏览器的工作流程的问题。该解决方案将有助于创建用于存储执行结果的必需目录。
祝您学习愉快!!
评论