Roku Сервіс
wdio-roku-service є пакетом від третьої сторони, для більш детальної інформації дивіться GitHub | npm Цей сервіс перевизначає багато частин WebdriverIO, щоб їх можна було використовувати з додатками Roku, та надає доступ до Roku ECP для управління Roku під час тестування.
Вимоги
Roku
Тестовий канал/channel.zip та пристрій Roku (з увімкненим режимом розробника) в тій же мережі, що й ваш комп'ютер Mac.
WebdriverIO
Це не самостійний продукт — він використовується як плагін тестового фреймворку WebdriverIO (або Сервіс на їхньому жаргоні). Перед використанням вам слід прой ти налаштування WDIO, запустивши npm init wdio@latest
.
Під час проходження налаштувань, щоб не доводилося переглядати всі питання/опції, ви можете просто вибрати такі варіанти під час фази ініціалізації:
- Roku Testing (ПРИМІТКА: Використовуйте це, якщо ваш репозиторій буде використовуватися тільки для тестування Roku, оскільки це стане типовим і єдиним встановленим сервісом. В іншому випадку використовуйте E2E Testing, щоб можна було встановити кілька сервісів.)
- On my local machine (E2E only)
- Web (E2E only)
- Chrome (E2E only)
- Mocha
- Typescript [modules працює для TS і JS, тому виберіть будь-який]
- autogenerate some test files (Y) -- default location
- page objects (Y) -- default location
- spec reporter
- additional plugins (N)
- Visual Testing (N)
- services (roku)
- npm install (Y)
Typescript Config
Якщо ви хочете використовувати Typescript для написання тестів, вам потрібно переконатися, що наступні опції встановлені у файлі tsconfig.json, згенерованому Webdriverio.
"moduleResolution": "nodenext",
"module": "NodeNext",
Потім ви можете використовувати сервіс, імпортуючи його у свої тести, як детально описано нижче.
WDIO Config
На даний момент тестування підтримується лише для одного пристрою Roku. Потрібні такі оновлення конфігурації:
maxInstances
таmaxInstancesPerCapability
повинні бути 1. Автоматичне тестування на кількох пристроях не підтримується і призведе до дублювання команд, що надсилаються на Roku. Має бути лише одна можливість.
//wdio.conf.js
export const config: WebdriverIO.Config = {
maxInstances: 1,
capabilities: [{
browserName: 'chrome'
// or if you want headless mode:
browserName: 'chrome',
'goog:chromeOptions': {
args: ['--headless', '--disable-gpu']
}
}],
//...
}
- Рекомендується збільшити
waitforInterval
іwaitforTimeout
, оскільки кожен інтервал передбачає завантаження xml з Roku. Щоб отримати більше від функціїbrowser.debug()
, ви також можете вирішити розширити час очікування для тестового запуску mocha до 5+ хвилин для розробницького середовища.
//wdio.conf.js
export const config: WebdriverIO.Config = {
waitforTimeout: 30000,
//optional:
mochaOpts: {
ui: 'bdd',
timeout: 600000
},
//...
}
Ви готові написати свій перший тест!
import { installFromZip } from 'wdio-roku-service/install'
import { exitChannel } from 'wdio-roku-service/channel'
import { Buttons, keyPress, keySequence } from 'wdio-roku-service/controller'
describe('first test', () => {
before('On the landing screen of the test channel', async () => {
await installFromZip(process.env.ROKU_APP_PATH)
})
it('should launch to the homescreen without login', async () => {
await $("//LoadingIndicator").waitForDisplayed({ reverse: true })
await expect($("//ContentCarousel")).toBeDisplayed()
})
after('should return to home', async () => {
await exitChannel()
})
})
Також рекомендується використовувати функцію browser.debug()
у wdio для зупинки тесту для налагодження та створення тестів:
// ...
it('should launch to the homescreen without login', async () => {
await $("//LoadingIndicator").waitForDisplayed({ reverse: true })
await expect($("//ContentCarousel")).toBeDisplayed()
await browser.debug()
// the test halts, a REPL becomes available for commands
Якщо chrome не запущений у headless режимі, ви можете побачити останній раз, коли було викликано openRokuXML()
(ймовірно через waitForX
або expect
). Використовуючи REPL у вашому терміналі, ви можете використовувати будь-які дійсні команди $
і кілька ключових спеціальних команд, які додані (browser.openRokuXML()
і browser.saveScreenshot('path/to/ss.jpg')
) — клас controller
не приєднаний до об'єкта browser
, тому ви не можете використовувати його зараз. На щастя, ви, ймовірно, сидите поруч з Roku і маєте пульт, яким можете користуватися для навігації і час від часу викликати browser.openRokuXML()
, щоб побачити, що сталося зі станом сторінки! І пам'ятайте, що XML працює з xpathing у самому браузері chrome, тож ви можете оцінювати/розробляти свої селектори безпосередньо в консолі chrome під час налагодження.
.env
Див. файл .env.example
. Скопіюйте його та перейменуйте на .env
у вашому проекті WebdriverIO, який використовує цей сервіс. Ви, ймовірно, захочете також додати його до .gitignore.
ROKU_IP
має бути IP-адресою вашого Roku. Команди будуть використовувати цей IP для зв'язку з ним. Це обов'язково.ROKU_USER
іROKU_PW
: Облікові дані для входу потрібні для встановлення архіву, а також для створення знімків екрана.ROKU_APP_PATH
має бути абсолютним шляхом до zip-файлу каналу Roku.ROKU_CHANNEL_ID
має бути ID каналу вашого Roku (зазвичай це "dev").DEBUG=wdio-roku-service
увімкне повідомлення для налагодження. Видаліть '#' на початку рядка, якщо хочете їх бачити.
Змінені функції
Browser
waitUntil
буде отримувати xml з Roku на кожній ітерації, щоб перевірити зміни.saveScreenshot
завантажить знімок екрана поточного екрана з Roku. Зокрема, ці знімки екрана мають формат .jpg, а не .png, який зазвичай використовує WebdriverIO.openRokuXML
отримає xml з Roku, якщо вам потрібно зробити це вручну, а не з очікуваннями.
Elements
- Усі очікування підтримуються так само, як і Browser.
waitForClickable
відображається наwaitForDisplayed
, аwaitForStable
відображається наwaitForExist
. click
,doubleClick
іmoveTo
не підтримуються. Ви повинні вручну переміщатися по додатку.isFocused
перевірить атрибутfocused
на елементі, що дорівнює true.isDisplayed
перевірить атрибутbounds
на елементі і переконається, щоvisible
не встановлений на false. Якщо встановленийwithinViewport
, межі порівнюватимуться з розміром екрана Roku.getSize
іgetLocation
беруть значення з атрибутаbounds
, повертаючи 0 для розміру і -Infinity для позиції, якщо атрибут відсутній.
Інші функції не змінювалися, але багато з них все ще працюють як очікувалося.
Matchers
Більшість матчерів були оновлені для отримання xml під час очікування. Деякі мають дещо іншу функціональність.
toBeDisplayed
,toBeDisplayedInViewport
,toBeFocused
,toBeExisting
,toBePresent
,toExist
,toHaveSize
,toHaveWidth
,toHaveHeight
, іtoHaveAttribute
всі працюють як очікувалося, з урахуванням змін у Element.toHaveElementProperty
відображається наtoHaveAttribute
.toHaveElementClass
перевіряє атрибутname
елемента.toHaveId
відображається наtoHaveElementClass
.toHaveText
перевіряє атрибутtext
елемента.toHaveChildren
перевіряє атрибутchildren
елемента.toHaveHTML
буде обробляти xml так, ніби це HTML, хоча це, ймовірно, не дуже корисно.
Наступні зараз не підтримуються:
toBeSelected
- Може бути підтримано незабаром після визначення того, як виглядає xml для вибраних кнопок, якщо є різниця.toBeChecked
- Може бути підтримано незабаром після визначення того, як виглядає xml для відмічених прапорців, якщо є різниця.toHaveComputedLabel
- Якщо у вас є еквівалент цього на елементах Roku, перевірте атрибут за допомогоюtoHaveAttribute
.toHaveComputedRole
- Якщо у вас є еквівалент цього на елементах Roku, перевірте атрибут за допомогоюtoHaveAttribute
.toHaveHref
- Якщо у вас є URL-адреси на елементах Roku, перевірте атрибут за допомогоюtoHaveAttribute
.toHaveStyle
- Елементи xml не мають стилів.toHaveClipboardText
- Це невідомо.toHaveTitle
- Заголовок буде випадково згенерованим тимчасовим іменем файлу xml.toHaveUrl
- URL-адреса буде шляхом до xml-файлу на вашому комп'ютері.
Використання
Встановлення каналу
Це вимагає, щоб вашому каналу був призначений ідентифікатор.
import { installByID } from 'wdio-roku-service/install';
async before() {
await installByID(process.env.ROKU_CHANNEL_ID);
}
Встановлення архіву
Рекомендується зберігати шлях в .env, особливо якщо у вас є кілька розробників, які можуть мати різні місця розташування та/або імена файлів.
import { installFromZip } from 'wdio-roku-service/install';
async before() {
await installFromZip(process.env.ROKU_ARCHIVE_PATH);
}
Попередньо встановлений канал
Якщо ви вже встановили канал самостійно перед тестуванням, ви можете просто запустити його.
import { launchChannel, exitChannel } from 'wdio-roku-service/channel';
async before() {
// Close the channel if it's already open. If the channel supports instant resume, this will merely background it
await exitChannel();
// Using the channel ID of 'dev' will launch the sideloaded application.
await launchChannel('dev');
}