Разделы портала

Онлайн-тренинги

.
Тестирование геолокации с Cypress
16.05.2023 00:00

Автор: Филип Рик (Filip Hric)
Оригинал статьи
Перевод: Ольга Алифанова

Современные сайты определяют местоположение пользователя множеством способов. Прежде, чем начать их тестировать, очень важно понять, как сайты это делают.

По сути для определения локации пользователя есть два основных способа. Во-первых, это использование вызова API к серверу – вызов может определить местоположение пользователя по тому, откуда он подключается. Во-вторых, это использование браузерного интерфейса геолокации, который дает фронтэнд-приложению координаты позиции.

Тестирование страницы цен

В тестируемом приложении есть страница цен. Она выводит цену в различных валютах в зависимости от того, откуда подключается пользователь – из ЕС, Великобритании, или откуда-то еще.

 

Более того, страница цен использует Паритет Покупательной Силы, чтобы давать некоторым странам скидку. За все это отвечает конечная точка GET /api/location. Она указывает на сервис, определяющий местоположение пользователя и возвращающий данные о стране плюс ряд других деталей. Ответ от сервера будет выглядеть примерно так:

{
"location": "sk",
"currency": "EUR",
"discountEligible": true,
"discountAmount": 20
}

Перехват запроса геолокации

Чтобы узнать, правильно ли работает наш фронтэнд, можно перехватить вызов API и передать в качестве ответа наши собственные данные. К примеру, можно поменять атрибуты локации и валюты, написав тест вот так:

cy.intercept('GET', '/api/location', {
location: 'UK',
currency: 'GBP'
})
cy.visit('/pricing')

В результате страница отрисуется так, как будто открыта из Великобритании, с фунтами (£) в качестве основной валюты. Заметьте, что сама цена тоже изменилась. Обычно это требует тестирования, чтобы убедиться, что цены на странице верные.

 

Тут можно протестировать различные комбинации валют, местоположений и права на скидку. Так как фронтэнд полагается на API для определения геолокации пользователя, мы изолируем фронтэнд и проверяем различные случаи на основании имитированного ответа API.

Браузерная геолокация

При помощи браузерного API геолокации пользователи могут разрешать браузеру передавать в приложение свои координаты. Этим пользуется множество сайтов, чтобы определить ваше местоположение и предоставить вам, скажем, рекомендации ресторанов поблизости. Если вы сталкивались с этим диалоговым окном, то видели API геолокации в действии:

 

В нашем приложении есть кнопка "Определить мое местоположение", открывающая карту с вашими координатами по клику. Пытаясь автоматизировать это в Cypress, мы немедленно столкнемся с проблемой:

 

В верхнем левом углу можно увидеть запрос геолокации в окне Cypress. Так как Cypress работает внутри браузера, подтвердить это диалоговое окно невозможно. Однако у нас есть два способа справиться с этим – использовать плагин, автоматически разрешающий определять геолокацию, или задать свои координаты.

Плагин разрешений браузера

Этот симпатичный плагин позволяет выдавать или отзывать определенные разрешения браузера прямо внутри нашего набора тестов. Нам потребуется ряд шагов, чтобы плагин заработал. После его установки нужно зарегистрировать функцию внутри функции setupNodeEvents. И, наконец, нужно передать env в объект browserPermissions, где мы задаем правила для разных разрешений. Все это объясняется в файле плагина README.md.

  cypress.config.js
import { defineConfig } from 'cypress'
import { cypressBrowserPermissionsPlugin } from 'cypress-browser-permissions'
 
export default defineConfig({
e2e: {
setupNodeEvents(on, config) {
config = cypressBrowserPermissionsPlugin(on, config)
},
env: {
'browserPermissions': {
'geolocation': 'allow',
}
}
}
})

Настройка этого плагина автоматически разрешит определение геолокации. Это как автоматически кликать по кнопке "разрешить" в упомянутом уже диалоговом окне.

Ввод собственных данных

Используя API геолокации, фронтэнд вызывает его внутри браузера. API геолокации доступно в объекте окна под навигационной панелью. Иными словами, когда приложение хочет получить данные о местоположении пользователя у браузера, оно вызывает примерно такую функцию:

window.navigator.geolocation.getCurrentPosition()

Вызов этой функции возвращает координаты местоположения или выдает ошибку. С этим можно работать разными способами (узнать о них можно в документации API геолокации). В нашем приложении мы берем координаты и передаем их в объект карты, который отрисовывает наше место на карте на основании полученных координат.

При помощи Cypress мы можем заменить реальные координаты, передаваемые браузером, на наши собственные. Это означает, что тест будет отображать карту одинаково вне зависимости от того, локальный это запуск или где-то на другом конце вселенной.

cy.visit('/pricing', {
onBeforeLoad ({ navigator }) {
// Košice city
const latitude = 48.71597183246423
const longitude = 21.255670821215418
cy.stub(navigator.geolocation, 'getCurrentPosition')
.callsArgWith(0, { coords: { latitude, longitude } })
}
})

Это решение я нашел на stackoverflow, и его хорошо продемонстрировал Йоан Солдереа в своем видео.

Это может казаться хитростью, но решение для нашего теста хорошее – в основном потому, что мы имеем дело с функциональностью самого браузера. Эта функциональность не относится к коду нашего приложения, однако мы используем данные от этого API, и нам надо убедиться, что они правильно обрабатываются. Поэтому важно проверить, что карта действительно отображается в DOM. В таких сценариях очень полезны инструменты визуального тестирования вроде Applitools.

Обсудить в форуме