Как автоматизировать вход в систему в Selenium

🔥 Важное для QA-специалистов! 🔥
В QaRocks ты найдешь туториалы, задачи и полезные книги, которых нет в открытом доступе. Уже более 15.000 подписчиков – будь среди нас! Заходи к нам в телеграм канал QaRocks

Во время написания автотестов с использованием Selenium часто возникает необходимость автоматизировать процесс входа в систему на сайте (web login).

Если не тестируется непосредственно сама форма входа в систему, тогда нет смысла проходить через эту форму в каждом тесте. Это замедляет выполнение автотестов и приводит к трате времени на лишние действия. Есть несколько способов обойти ручной ввод логина — и в этой статье мы рассмотрим основные.

Когда вы определите, какой POST-запрос отправляется при нажатии кнопки “Войти” в форме, его можно перехватить и воспроизвести через curl.

Форма входа с заполненным полем пароля и кнопкой "Sign In".
Инструменты разработчика в браузере, вкладка "Network". В подменю выбрано "Copy Value", затем - "Copy as Fetch"

Получив этот запрос, попробуйте выполнить его в консоли — он может выглядеть примерно так:

await fetch("/api/authentication/token", {
    "credentials": "include",
    "headers": {
        "Content-Type": "application/json",
        "X-Requested-With": "XMLHttpRequest",
    },
    "referrer": "https://searchui-v2-test-data.nonprod.eu-west-2.aws.dat.corp.hmrc.gov.uk/login?returnUrl=declarations",
    "body": "{"username":"UID","password":"pass"}",
    "method": "POST"
});

Если авторизация через токен, возможно, потребуется вручную его установить. Иногда достаточно сделать это в браузере.

Что касается срока действия токена и его проверки на сервере:
Обратите внимание, что способ установки token и tokenExpiry зависит от того, какие значения ожидает сервер. В примере выше сервер просто проверяет, чтобы tokenExpiry был больше текущего времени в формате epoch time.

1. Использование fetch в JavaScript-вызовах в браузере

Можно выполнить запрос с помощью fetch прямо в консоли, а затем убедиться, что он работает.

await fetch("/api/authentication/token", {
    ...
})
.then(res => res.json())
.then(data => {
  // Extract token from the response
  const token = data.token;

  // Set token in session storage
  localStorage.setItem('token', data.token);
  localStorage.setItem('tokenExpiry', '1903163542236');
  
  // redirect to home page after authentication is set      
  window.location.assign("https://homepageurl/");
});

Учтите, что метод window.location.assign() выполняет редирект на главную страницу после завершения авторизации.

А что если после этого вы хотите выполнить другой запрос, используя полученный токен? Например, отправить запрос к API для получения списка элементов, где требуется Bearer-токен?

await fetch("/api/authentication/token", {
    ...
})
.then(res => res.json())
.then(data => {
  const token = data.token;
  localStorage.setItem('token', data.token);
  localStorage.setItem('tokenExpiry', '1903163542236');
  window.location.assign("https://homePageUrl/");
  
  const auth_string = "Bearer " + token;
  fetch("/api/filters", {
     "credentials": "include",
     "headers": {
      "Content-Type": "application/json",
      "X-Requested-With": "XMLHttpRequest",
      "Authorization": auth_string,
     },
     "method": "GET"
  });
});

А как реализовать это в рамках фреймворка автоматизации, например, с использованием Selenium на Java? Просто выполните указанный выше fetch-запрос через JavaScriptExecutor.

String fetchRequestString = "await fetch(...);"
((JavascriptExecutor) driver)..executeScript(fetchRequestString);

2. Получение токена напрямую через Java

Чтобы ещё больше сократить время выполнения, можно исключить выполнение fetch в браузере и связанные с этим задержки — токен можно получить напрямую, минуя браузер. В этом случае API вызывается с помощью библиотеки JSoup.

Читайте также: Скрипты для тестирования API в Postman

Такой запрос довольно просто сформировать: скопируйте POST-запрос из вкладки Network в браузере как curl, а затем преобразуйте его в код Java с помощью онлайн-инструментов (например, Convert curl to Java +JSoup):

String responseBody = Jsoup.connect("https://homePageUrl/api/authentication/token")
    .header("Content-Type", "application/json")
    .header("X-Requested-With", "XMLHttpRequest")
    .requestBody("{\"username\":\"" + username + "\",\"password\":\"" + password + "\"}")
    .method(Connection.Method.POST)
    .ignoreContentType(true)
    .execute()
    .body();

String token = JSONObject(responseBody).get("token").toString();

Получив токен, установите его в браузере, например, с помощью WebDriver на Java, записав токен в localStorage.

LocalStorage local = ((WebStorage) driver).getLocalStorage();
local.setItem("tokenExpiry", String.valueOf(Instant.now().toEpochMilli() + 10000));
driver.navigate().to(getTestConfig().getSearchHost());
driver.navigate.to(homePageUrl);

Или с помощью JavaScript и метода localStorage.setItem():

jsExecutor.executeScript("localStorage.setItem('token','" + token + "');");
jsExecutor.executeScript("localStorage.setItem('tokenExpiry', new Date().getTime() + 6000 * 1000);");
jsExecutor.executeScript("window.location.assign('" + homePageUrl + "');");

Примечание по работе с параметром tokenExpiry.
Обратите внимание, что метод установки tokenExpiry будет отличаться в зависимости от того, что ожидает сервер. В приведенном выше примере сервер ожидает, что время истечения токена будет больше текущего времени в формате epoch. Поэтому для него установлено соответствующее значение.

Перевод статьи «Automated web login».

🔥 Какой была ваша первая зарплата в QA и как вы искали первую работу? 

Мега обсуждение в нашем телеграм-канале о поиске первой работы. Обмен опытом и мнения.

Читать в телеграм

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *