Загрузка данных
package ru.sber.qa.playwright.configuration.config.impl;
import com.microsoft.playwright.Browser;
import com.microsoft.playwright.BrowserType;
import com.microsoft.playwright.Playwright;
import ru.sber.qa.playwright.configuration.scope.PlaywrightConfigScope;
import ru.sber.qa.playwright.configuration.selenoid.SelenoidCapabilities;
import ru.sber.qa.playwright.services.PlaywrightServiceConfiguration;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.function.Function;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public class DefaultPlaywrightServiceConfiguration implements PlaywrightServiceConfiguration {
private final Properties properties = new PlaywrightConfigScope().getProperties();
public DefaultPlaywrightServiceConfiguration() {
}
/**
* <p>Настройки запуска Playwright</p>
*/
protected Properties getProperties() {
return properties;
}
/**
* <p>Настройки запуска Playwright</p>
*
* @return {@link Playwright.CreateOptions}
*/
@Override
public Playwright.CreateOptions createOptions() {
Playwright.CreateOptions createOptions = new Playwright.CreateOptions();
Map<String, String> env = new HashMap<>();
// Включение отладки, но необходимо вручную задать путь до исходников через PLAYWRIGHT_JAVA_SRC
// Например PLAYWRIGHT_JAVA_SRC=.../main/java:.../test/java разделяя пути двоеточием.
if (Boolean.parseBoolean(properties.getProperty("web.playwright.debug"))) {
env.put("PWDEBUG", "1");
}
// Ссылка на скачивание браузеров
String downloadHost = properties.getProperty("web.playwright.download.host");
if (isNotBlank(downloadHost)) {
env.put("PLAYWRIGHT_DOWNLOAD_HOST", downloadHost);
}
// Отключение скачивание браузеров
if (Boolean.parseBoolean(properties.getProperty("web.playwright.browser.download.skip"))) {
env.put("PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD", "1");
} else {
env.put("NODE_TLS_REJECT_UNAUTHORIZED", "0");
}
// Путь к установленному NodeJS, если есть
String nodePath = properties.getProperty("web.playwright.nodejs.path");
if (isNotBlank(nodePath)) {
env.put("PLAYWRIGHT_NODEJS_PATH", nodePath);
}
// Путь к скачанным браузерам
String browserDownloadPath = properties.getProperty("web.playwright.browser.download.path");
if (isNotBlank(browserDownloadPath)) {
env.put("PLAYWRIGHT_BROWSERS_PATH", browserDownloadPath);
}
createOptions.setEnv(env);
return createOptions;
}
/**
* <p>Настройки запуска Playwright на Selenoid.</p>
*/
@Override
public BrowserType.ConnectOverCDPOptions connectOverCDPOptions() {
double timeout = Double.parseDouble(properties.getProperty("web.timeout"));
double slowMo = Double.parseDouble(properties.getProperty("web.playwright.step.delay"));
return new BrowserType.ConnectOverCDPOptions()
.setTimeout(timeout)
.setSlowMo(slowMo);
}
/**
* <p>Опции для Selenoid.</p>
*/
@Override
public SelenoidCapabilities selenoidCapabilities() {
// Для указания пути к бинарнику SberBrowser
boolean isSber = false;
// Во всех случаях, кроме edge результат будет chrome-о-подобный
String browserName = switch (properties.getProperty("web.browser.type").toLowerCase()) {
case "edge" -> "edge";
case "sber" -> {
isSber = true;
yield "chrome";
}
default -> "chrome";
};
SelenoidCapabilities capabilities = new SelenoidCapabilities()
.browserName(browserName)
.browserVersion(properties.getProperty("web.browser.version"));
if (isSber) {
capabilities.binaryPath("/usr/bin/sberbrowser-browser");
}
return capabilities
.enableVNC(Boolean.parseBoolean(properties.getProperty("web.enable.vnc")))
.setArgs(args())
.addPrefs(browserPreferences())
.screenResolution(properties.getProperty("web.browser.size"))
.setEnv(List.of(properties.getProperty("web.env.logs").split(";")))
.sessionTimeout(properties.getProperty("web.session.timeout"))
.downloadsEnabled(true);
}
/**
* <p>Настройки запуска браузера</p>
*
* @return {@link BrowserType.LaunchOptions}
*/
@Override
public BrowserType.LaunchOptions launchOptions() {
BrowserType.LaunchOptions launchOptions = new BrowserType.LaunchOptions();
String downloadPath = properties.getProperty("web.playwright.download.path");
if (isNotBlank(downloadPath)) {
launchOptions.setDownloadsPath(Path.of(downloadPath));
}
double timeout = Double.parseDouble(properties.getProperty("web.timeout"));
launchOptions.setTimeout(timeout);
if (Boolean.parseBoolean(properties.getProperty("web.playwright.headless"))) {
launchOptions.setHeadless(true);
} else {
launchOptions.setHeadless(false);
double slowMo = Double.parseDouble(properties.getProperty("web.playwright.step.delay"));
launchOptions.setSlowMo(slowMo);
}
String tracesPath = properties.getProperty("web.playwright.traces.path");
if (isNotBlank(tracesPath)) {
launchOptions.setTracesDir(Path.of(tracesPath));
}
// Chromium по умолчанию
String browserProp = properties.getProperty("web.playwright.browser");
Path executablePath = Path.of(browserProp);
if (executablePath.toFile().exists()) {
launchOptions.setExecutablePath(executablePath);
}
return launchOptions;
}
/**
* <p>Настройки запуска браузера</p>
*
* @return {@link BrowserType.LaunchPersistentContextOptions}
*/
@Override
public BrowserType.LaunchPersistentContextOptions launchPersistentContextOptions() {
BrowserType.LaunchPersistentContextOptions launchOptions = new BrowserType.LaunchPersistentContextOptions();
launchOptions.setArgs(args());
// Запись видео
boolean recordVideo = Boolean.parseBoolean(properties.getProperty("web.playwright.video"));
if (recordVideo) {
String videoPath = properties.getProperty("web.playwright.video.path");
if (isNotBlank(videoPath)) {
launchOptions.setRecordVideoDir(Path.of(videoPath));
}
}
String downloadPath = properties.getProperty("web.playwright.download.path");
if (isNotBlank(downloadPath)) {
launchOptions.setDownloadsPath(Path.of(downloadPath));
}
double timeout = Double.parseDouble(properties.getProperty("web.timeout"));
launchOptions.setTimeout(timeout);
if (Boolean.parseBoolean(properties.getProperty("web.playwright.headless"))) {
launchOptions.setHeadless(true);
} else {
launchOptions.setHeadless(false);
double slowMo = Double.parseDouble(properties.getProperty("web.playwright.step.delay"));
launchOptions.setSlowMo(slowMo);
}
String tracesPath = properties.getProperty("web.playwright.traces.path");
if (isNotBlank(tracesPath)) {
launchOptions.setTracesDir(Path.of(tracesPath));
}
// Chromium по умолчанию
String browserProp = properties.getProperty("web.playwright.browser");
Path executablePath = Path.of(browserProp);
if (executablePath.toFile().exists()) {
launchOptions.setExecutablePath(executablePath);
}
String size = properties.getProperty("web.browser.size");
if (isNotBlank(size)) {
String[] viewportSize = size.split("[xX]");
int width = Integer.parseInt(viewportSize[0]);
int height = Integer.parseInt(viewportSize[1]);
launchOptions.setViewportSize(width, height);
if (recordVideo) {
launchOptions.setRecordVideoSize(width, height);
}
}
return launchOptions;
}
/**
* <p>Определение типа браузера</p>
*
* @return функция, принимающая {@link Playwright} и возвращающая {@link BrowserType}
*/
@Override
public Function<Playwright, BrowserType> browserType() {
// Chromium по умолчанию
String browserProp = properties.getProperty("web.playwright.browser");
if (Path.of(browserProp).toFile().exists()) {
if (browserProp.contains("firefox")) {
return Playwright::firefox;
}
} else {
String browserTypeLower = browserProp.toLowerCase();
return switch (browserTypeLower) {
case "chromium" -> Playwright::chromium;
case "firefox" -> Playwright::firefox;
case "webkit" -> Playwright::webkit;
default -> {
// Ищем совпадение в пути
if (browserTypeLower.contains("firefox")) {
yield Playwright::firefox;
} else {
yield Playwright::chromium;
}
}
};
}
return Playwright::chromium;
}
/**
* <p>Настройки создания контекста</p>
*
* @return {@link Browser.NewContextOptions}}
*/
@Override
public Browser.NewContextOptions newContextOptions() {
Browser.NewContextOptions contextOptions = new Browser.NewContextOptions();
String viewport = properties.getProperty("web.browser.size");
// viewportSize в конфиге заполняется в формате 1234x5678
String[] viewportSize = viewport.split("[xX]");
int width = Integer.parseInt(viewportSize[0]);
int height = Integer.parseInt(viewportSize[1]);
contextOptions.setViewportSize(width, height);
// Запись видео
boolean recordVideo = Boolean.parseBoolean(properties.getProperty("web.playwright.video"));
if (recordVideo) {
contextOptions.setRecordVideoSize(width, height);
String videoPath = properties.getProperty("web.playwright.video.path");
if (isNotBlank(videoPath)) {
contextOptions.setRecordVideoDir(Path.of(videoPath));
}
}
contextOptions.setAcceptDownloads(true);
contextOptions.setIgnoreHTTPSErrors(true);
return contextOptions;
}
/**
* <p>Аргументы запуска браузера</p>
*
* @return список аргументов
* @see <a href="https://github.com/GoogleChrome/chrome-launcher/blob/main/docs/chrome-flags-for-tools.md">
* Chrome: Флаги запуска
* </a>
* @see <a href="https://peter.sh/experiments/chromium-command-line-switches/">
* Chrome: Command Line Switches
* </a>
* @see <a href="https://chromium.googlesource.com/chromium/src/+/master/chrome/common/chrome_switches.cc">
* Chrome: Switches
* </a>
*/
@Override
public List<String> args() {
// Самый минимум в случае SberBrowser
return List.of("--disable-features=SberAuth");
}
/**
* <p>Параметры конфигурации профиля (предпочтения браузера).</p>
*
* @see <a href="https://chromium.googlesource.com/chromium/src/+/HEAD/chrome/common/pref_names.h">
* Chrome: Полный список возможных значений.
* </a>
* @see <a href="https://kb.mozillazine.org/About:config_entries">
* Firefox: Полный список возможных значений.
* </a>
*/
@Override
public Map<String, Object> browserPreferences() {
Map<String, Object> prefs = new HashMap<>(Map.of(
"credentials_enable_service", false,
"profile.password_manager_enabled", false,
"browser.show_update_promotion_info_bar", false,
"profile.default_content_setting_values.popups", 2,
"plugins.always_open_pdf_externally", true,
"plugins.plugins_disabled", List.of(
"Chrome PDF Viewer"
)
));
List<String> certSelectors = autoSelectCertificates();
if (!certSelectors.isEmpty()) {
prefs.put("profile.managed_auto_select_certificate_for_urls", certSelectors);
}
return prefs;
}
/**
* <p>При потребности использовать -
* расширить {@link DefaultPlaywrightServiceConfiguration} и переопределить этот метод.</p>
* <p>Пример:</p>
* <pre>{@code
* @Override
* public List<String> autoSelectCertificates() {
* return List.of(
* certificateSelector()
* .pattern("https://auth-dbz.delta.sbrf.ru")
* .issuer("SberCA Ext", "Sberbank of Russia")
* .subject(personalLogin, "Sberbank")
* .build()
* );
* }
* }</pre>
*/
public List<String> autoSelectCertificates() {
return List.of();
}
/**
* <p>Запрашивается ли запуск через Selenoid</p>
*/
@Override
public boolean isRemote() {
return Boolean.parseBoolean(properties.getProperty("web.playwright.remote"));
}
/**
* <p>Базовый URL</p>
*/
public String getBaseUrl() {
return properties.getProperty("web.base.url");
}
}