Chrome DevTools — это набор инструментов, встроенных непосредственно в браузеры на базе Chromium, такие как Chrome, Opera и Microsoft Edge, которые помогают разработчикам отлаживать и изучать веб-сайты.
С помощью Chrome DevTools разработчики получают более глубокий доступ к веб-сайтам и могут:
Selenium — это комплексный набор инструментов и библиотек, поддерживающих автоматизацию веб-браузера. В Selenium 4 добавлена встроенная поддержка Chrome DevTools API. Благодаря этим новым API наши тесты теперь могут:
Это лишь верхушка айсберга!
В Selenium 4 представлен новый класс ChromiumDriver, который включает два метода доступа к Chrome DevTools: getDevTools() и ExecuteCdpCommand().
Метод getDevTools() возвращает новый объект DevTools, который позволяет отправлять встроенные команды Selenium для CDP с помощью метода send(). Эти команды представляют собой методы-оболочки, которые делают вызов функций CDP более понятным и простым.
Метод ExecuteCdpCommand() также позволяет выполнять методы CDP, но он более примитивен. Вместо использования завернутого API он позволяет напрямую передавать команду Chrome DevTools и аргументы этой команды. Если для команды CDP нет API-оболочки Selenium или вы хотите вызвать его иначе, чем API Selenium, вы можете использовать ExecuteCdpCommand().
Драйверы на основе Chromium, такие как ChromeDriver и EdgeDriver, теперь наследуются от ChromiumDriver, поэтому вы также можете получить доступ к API Selenium CDP из этих драйверов.
Давайте рассмотрим, как вы можете использовать эти новые API Selenium 4 для решения различных вариантов использования.
Большинство приложений, которые мы создаем сегодня, отвечают потребностям конечных пользователей на различных платформах, устройствах (например, мобильных устройствах, планшетах, носимых устройствах, настольных компьютерах) и ориентациях экрана.
Как тестировщики, мы можем захотеть разместить наши приложения разных размеров, чтобы обеспечить более быстрое реагирование приложения.
Как мы можем добиться этого, используя новую функциональность CDP Selenium?
Команда CDP для изменения показателей устройства — Emulation.setDeviceMetricsOverride, и эта команда требует ввода ширины, высоты, флага мобильного устройства и коэффициента масштабирования устройства. Эти четыре ключа необходимы в этом сценарии, но есть и некоторые дополнительные ключи.
В наших тестах Selenium мы можем использовать метод DevTools::send() и использовать встроенную команду setDeviceMetricsOverride(), но этот Selenium API принимает 12 параметров — помимо 4 обязательных параметров есть 8 необязательных. Для любого из этих 8 дополнительных параметров, которые нам не нужно отправлять, мы можем передатьOptional.empty().
Однако, чтобы упростить этот процесс и передать только необходимые параметры, я буду использовать исходный метод ExecuteCdpCommand() в приведенном ниже коде.
package com.devtools;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import java.util.HashMap;
import java.util.Map;
public class SetDeviceMode {
final static String PROJECT_PATH = System.getProperty("user.dir");
public static void main(String[] args){
System.setProperty("webdriver.chrome.driver", PROJECT_PATH + "/src/main/resources/chromedriver");
ChromeDriver driver;
driver = new ChromeDriver();
DevTools devTools = driver.getDevTools();
devTools.createSession();
Map deviceMetrics = new HashMap()
{{
put("width", 600);
put("height", 1000);
put("mobile", true);
put("deviceScaleFactor", 50);
}};
driver.executeCdpCommand("Emulation.setDeviceMetricsOverride", deviceMetrics);
driver.get("https://www.google.com");
}
}
В строке 19 я создаю карту, содержащую ключи, необходимые для этой команды.
Затем в строке 26 я вызываю метод ExecuteCdpCommand(), передавая два параметра: имя команды «Emulation.setDeviceMetricsOverride» и карту метрик устройства, содержащую параметры.
В строке 27 я открываю домашнюю страницу Google, созданную с учетом предоставленных мной спецификаций, как показано ниже.
С помощью такого решения, как Applitools Eyes, мы можем не только быстро тестировать различные области просмотра с помощью этих новых команд Selenium, но также можем устранять любые несоответствия в масштабе. Eyes достаточно умен, чтобы не сообщать о неверных результатах при небольших и незаметных изменениях в пользовательском интерфейсе из-за разных браузеров и областей просмотра.
Во многих случаях нам необходимо протестировать определенные функции, основанные на местоположении, такие как предложения, цены на основе местоположения и т. д. Для этого мы можем использовать API DevTools для имитации местоположения.
@Test
public void mockLocation(){
devTools.send(Emulation.setGeolocationOverride(
Optional.of(48.8584),
Optional.of(2.2945),
Optional.of(100)));
driver.get("https://mycurrentlocation.net/");
try {
Thread.sleep(30000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Многие пользователи получают доступ к веб-приложениям через портативные устройства, подключенные к Wi-Fi или сотовым сетям. Часто наблюдается слабый сигнал сети и, следовательно, медленное подключение к Интернету.
В ситуациях, когда у вас медленное подключение к Интернету (2G) или периодические отключения, может быть важно проверить, как ваше приложение ведет себя в таких условиях.
Команда CDP для подделки сетевых подключений — Network.emulateNetworkConditions. Информацию об обязательных и необязательных параметрах этой команды можно найти в документации.
Получив доступ к Chrome DevTools, вы можете смоделировать эти сценарии. Давайте посмотрим, как это сделать.
package com.devtools;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.network.Network;
import org.openqa.selenium.devtools.network.model.ConnectionType;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
public class SetNetwork {
final static String PROJECT_PATH = System.getProperty("user.dir");
public static void main(String[] args){
System.setProperty("webdriver.chrome.driver", PROJECT_PATH + "/src/main/resources/chromedriver");
ChromeDriver driver;
driver = new ChromeDriver();
DevTools devTools = driver.getDevTools();
devTools.createSession();
devTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty()));
devTools.send(Network.emulateNetworkConditions(
false,
20,
20,
50,
Optional.of(ConnectionType.CELLULAR2G)
));
driver.get("https://www.google.com");
}
}
В строке 21 мы получаем объект DevTools, вызывая метод getDevTools(). Затем мы вызываем метод send(), чтобы включить сеть, и снова вызываем метод send(), передавая встроенную команду Network.emulateNetworkConditions() и параметры, которые мы хотим отправить с помощью этой команды.
Наконец, мы открываем домашнюю страницу Google, используя моделируемые условия сети.
Используя DevTools, мы можем захватывать HTTP-запросы, сделанные приложениями, и методы доступа, данные, заголовки и многое другое.
Давайте посмотрим, как захватить HTTP-запрос, URI и метод запроса, используя пример кода.
package com.devtools;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.network.Network;
import java.util.Optional;
public class CaptureNetworkTraffic {
private static ChromeDriver driver;
private static DevTools chromeDevTools;
final static String PROJECT_PATH = System.getProperty("user.dir");
public static void main(String[] args){
System.setProperty("webdriver.chrome.driver", PROJECT_PATH + "/src/main/resources/chromedriver");
driver = new ChromeDriver();
chromeDevTools = driver.getDevTools();
chromeDevTools.createSession();
chromeDevTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty()));
chromeDevTools.addListener(Network.requestWillBeSent(),
entry -> {
System.out.println("Request URI : " + entry.getRequest().getUrl()+"\n"
+ " With method : "+entry.getRequest().getMethod() + "\n");
entry.getRequest().getMethod();
});
driver.get("https://www.google.com");
chromeDevTools.send(Network.disable());
}
}
Команда CDP для начала захвата сетевого трафика — Network.enable. Информацию об обязательных и необязательных параметрах этой команды можно найти в документации.
В нашем коде строка 22 использует метод DevTools::send() для отправки команды Network.enable CDP для включения захвата сетевого трафика.
В строке 23 добавляется прослушиватель, который прослушивает все запросы, отправленные приложением. Для каждого запроса, перехваченного приложением, мы извлекаем URL-адрес с помощью getRequest().getUrl() и метода HTTP с помощью getRequest().getMethod().
В строке 29 мы открываем домашнюю страницу Google и выводим на консоль URI и метод HTTP всех запросов, сделанных этой страницей.
Как только мы закончим захват запроса, мы можем отправить команду CDP Network.disable, чтобы прекратить захват сетевого трафика, как показано в строке 30.
Чтобы перехватить ответ, мы будем использовать событие Network.responseReceived. Это событие срабатывает, когда доступен HTTP-ответ, мы можем прослушивать URL-адрес, заголовки ответа, код ответа и т. д. Чтобы получить тело ответа, используйте метод Network.getResponseBody.
@Test
public void validateResponse() {
final RequestId[] requestIds = new RequestId[1];
devTools.send(Network.enable(Optional.of(100000000), Optional.empty(), Optional.empty()));
devTools.addListener(Network.responseReceived(), responseReceived -> {
if (responseReceived.getResponse().getUrl().contains("api.zoomcar.com")) {
System.out.println("URL: " + responseReceived.getResponse().getUrl());
System.out.println("Status: " + responseReceived.getResponse().getStatus());
System.out.println("Type: " + responseReceived.getType().toJson());
responseReceived.getResponse().getHeaders().toJson().forEach((k, v) -> System.out.println((k + ":" + v)));
requestIds[0] = responseReceived.getRequestId();
System.out.println("Response Body: \n" + devTools.send(Network.getResponseBody(requestIds[0])).getBody() + "\n");
}
});
driver.get("https://www.zoomcar.com/bangalore");
driver.findElement(By.className("search")).click();
}
Мы все полагаемся на журналы для отладки и анализа сбоев. При тестировании и работе с приложениями с конкретными данными или конкретными условиями журналы могут помочь нам отлаживать и фиксировать сообщения об ошибках, предоставляя дополнительную информацию, публикуемую на вкладке консоли Chrome DevTools.
Мы можем собирать журналы консоли с помощью нашего сценария Selenium, вызвав команду журнала CDP, как показано ниже.
package com.devtools;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.log.Log;
public class CaptureConsoleLogs {
private static ChromeDriver driver;
private static DevTools chromeDevTools;
final static String PROJECT_PATH = System.getProperty("user.dir");
public static void main(String[] args){
System.setProperty("webdriver.chrome.driver", PROJECT_PATH + "/src/main/resources/chromedriver");
driver = new ChromeDriver();
chromeDevTools = driver.getDevTools();
chromeDevTools.createSession();
chromeDevTools.send(Log.enable());
chromeDevTools.addListener(Log.entryAdded(),
logEntry -> {
System.out.println("log: "+logEntry.getText());
System.out.println("level: "+logEntry.getLevel());
});
driver.get("https://testersplayground.herokuapp.com/console-5d63b2b2-3822-4a01-8197-acd8aa7e1343.php");
}
}
В нашем коде строка 19 использует DevTools::send() для включения записи журнала консоли.
Затем мы добавляем прослушиватель для сбора всех журналов консоли, регистрируемых приложением. Для каждого журнала, полученного приложением, мы извлекаем текст журнала с помощью метода getText() и уровень журнала с помощью метода getLevel().
Наконец, откройте приложение и запишите журнал ошибок консоли, опубликованный приложением.
В современном быстро меняющемся мире, где мы итеративно создаем программное обеспечение, нам также следует итеративно выявлять узкие места в производительности. Плохо работающие веб-сайты и страницы, которые медленно загружаются, могут оставить клиентов недовольными.
Можем ли мы проверять эти показатели в каждой сборке? Да, мы можем!
Сбор показателей производительностииз CDP Команда Производительность.включить. Информацию об этой команде можно найти в документации.
Давайте посмотрим, как этот процесс выполняется в Selenium 4 и Chrome DevTools API.
package com.devtools;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.performance.Performance;
import org.openqa.selenium.devtools.performance.model.Metric;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class GetMetrics {
final static String PROJECT_PATH = System.getProperty("user.dir");
public static void main(String[] args){
System.setProperty("webdriver.chrome.driver", PROJECT_PATH + "/src/main/resources/chromedriver");
ChromeDriver driver = new ChromeDriver();
DevTools devTools = driver.getDevTools();
devTools.createSession();
devTools.send(Performance.enable());
driver.get("https://www.google.org");
List<Metric> metrics = devTools.send(Performance.getMetrics());
List<String> metricNames = metrics.stream()
.map(o -> o.getName())
.collect(Collectors.toList());
devTools.send(Performance.disable());
List<String> metricsToCheck = Arrays.asList(
"Timestamp", "Documents", "Frames", "JSEventListeners",
"LayoutObjects", "MediaKeySessions", "Nodes",
"Resources", "DomContentLoaded", "NavigationStart");
metricsToCheck.forEach( metric -> System.out.println(metric +
" is : " + metrics.get(metricNames.indexOf(metric)).getValue()));
}
}
Сначала мы создаем сеанс, вызывая метод createSession() DevTools, как показано в строке 19.
Далее мы проходим Performance.enable() команда отправлена на send() чтобы включить DevTools Приходить Сбор показателей производительности,Такой как первый20указание строки。
Как только захват производительности включен, мы можем открыть приложение и поместить Performance.getMetrics() команда отправлена на отправлять(). Это вернет Metric Список объектов, которые мы можем передать в потоковом режиме, чтобы получить имена всех захваченных метрик, как показано в строке 25.
Затем мы проходим Performance.disable() команда отправлена на send() чтобы отключить захват производительности, как показано в строке 29.
Чтобы просмотреть интересующие нас метрики, мы определяем список под названием metricsToCheck, а затем печатаем значения метрик, проходя по списку.
В Selenium невозможно взаимодействовать со всплывающими окнами браузера, поскольку он может взаимодействовать только с элементами DOM. Это создает проблему для всплывающих окон, таких как диалоги аутентификации.
Мы можем сделать это, используя CDP API непосредственно с DevTools Обработайте аутентификацию, чтобы обойти эту проблему. Устанавливает дополнительные заголовки для запроса CDP Команда Network.setExtraHTTPHeaders。
Вот как вызвать эту команду в Selenium 4.
package com.devtools;
import org.apache.commons.codec.binary.Base64;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.network.Network;
import org.openqa.selenium.devtools.network.model.Headers;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
public class SetAuthHeader {
private static final String USERNAME = "guest";
private static final String PASSWORD = "guest";
final static String PROJECT_PATH = System.getProperty("user.dir");
public static void main(String[] args){
System.setProperty("webdriver.chrome.driver", PROJECT_PATH + "/src/main/resources/chromedriver");
ChromeDriver driver = new ChromeDriver();
//Create DevTools session and enable Network
DevTools chromeDevTools = driver.getDevTools();
chromeDevTools.createSession();
chromeDevTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty()));
//Open website
driver.get("https://jigsaw.w3.org/HTTP/");
//Send authorization header
Map<String, Object> headers = new HashMap<>();
String basicAuth ="Basic " + new String(new Base64().encode(String.format("%s:%s", USERNAME, PASSWORD).getBytes()));
headers.put("Authorization", basicAuth);
chromeDevTools.send(Network.setExtraHTTPHeaders(new Headers(headers)));
//Click authentication test - this normally invokes a browser popup if unauthenticated
driver.findElement(By.linkText("Basic Authentication test")).click();
String loginSuccessMsg = driver.findElement(By.tagName("html")).getText();
if(loginSuccessMsg.contains("Your browser made it!")){
System.out.println("Login successful");
}else{
System.out.println("Login failed");
}
driver.quit();
}
}
Сначала мы создаем сеанс, используя объект DevTools, и включаем Network. Это показано в строках 25-26.
Затем мы открываем наш веб-сайт и создаем заголовки аутентификации для отправки.
В строке 35 мы отправляем команду setExtraHTTPHeaders в функцию send() вместе с данными заголовка. Эта часть аутентифицирует нас и позволит нам обойти всплывающие окна браузера.
Чтобы протестировать эту функцию,Мы перешли по ссылке Базовая аутентификациятест. Если вы попробуете это вручную,Вы увидите всплывающее окно Браузер с просьбой войти в систему. Но поскольку мы отправляем заголовок аутентификации,Поэтому в нашем скрипте это всплывающее окно не появится.
Вместо этого мы получаем сообщение «Вход в ваш браузер прошел успешно!».
добавив CDP API,Selenium стал сильнее. Теперь мы можем улучшить наш тест, чтобы захватить HTTP сетевой трафик, собирать показатели производительности, обрабатывать аутентификацию и имитировать географическое положение, часовой пояс и режим устройства. и существовать Chrome DevTools Любые другие функции, которые могут появиться в!
Связь:https://zhuanlan.zhihu.com/p/639947455