Protractor — инструмент для энд-ту-энд тестирования
Angular-приложений, однако он поддерживает и не-Angular сайты через
browser.waitForAngularEnabled(false). Для работы с
современными веб-компонентами важно убедиться, что окружение правильно
настроено: Node.js, npm и WebDriver Manager.
Настройка проекта:
npm install -g protractor
webdriver-manager update
Создание конфигурационного файла protractor.conf.js:
exports.config = {
framework: 'jasmine',
seleniumAddress: 'http://localhost:4444/wd/hub',
specs: ['specs/*.spec.js'],
capabilities: {
browserName: 'chrome'
},
onPrepare: () => {
browser.waitForAngularEnabled(false);
}
};
Флаг waitForAngularEnabled(false) отключает ожидание
Angular, что необходимо для тестирования веб-компонентов на чистом
JavaScript.
Веб-компоненты создаются через Custom Elements
(<my-component>). Для работы с ними Protractor
предоставляет стандартные локаторы, однако важно учитывать теневое
дерево (Shadow DOM).
Примеры локаторов:
element(by.tagName('my-component'))element(by.css('[data-test="submit-button"]'))element(by.xpath('//my-component[text()="Click me"]'))Для элементов внутри Shadow DOM необходимо использовать JavaScript-выражения, так как стандартные локаторы не проникают в теневой корень:
const shadowRoot = element(by.tagName('my-component')).getWebElement()
.then(el => el.shadowRoot);
const buttonInShadow = shadowRoot.then(root => root.querySelector('button'));
Protractor наследует все методы WebDriver для кликов, ввода текста и ожиданий. Основные подходы при работе с веб-компонентами:
await element(by.css('my-component button')).click();
await element(by.css('my-component input')).sendKeys('Тестовый текст');
const text = await element(by.css('my-component .label')).getText();
Особенность веб-компонентов заключается в том, что изменения DOM могут быть асинхронными. Поэтому важно использовать ожидания:
const EC = protractor.ExpectedConditions;
const myButton = element(by.css('my-component button'));
await browser.wait(EC.elementToBeClickable(myButton), 5000);
await myButton.click();
В веб-компонентах часто используются асинхронные обновления. Для
корректного взаимодействия рекомендуется комбинировать
await с ExpectedConditions:
const input = element(by.css('my-component input'));
await browser.wait(EC.visibilityOf(input), 5000);
await input.sendKeys('Тест');
Для элементов внутри Shadow DOM:
const shadowHost = element(by.tagName('my-component')).getWebElement();
const shadowRoot = await browser.executeScript('return arguments[0].shadowRoot', shadowHost);
const shadowButton = await shadowRoot.findElement(By.css('button'));
await shadowButton.click();
executeScript позволяет выполнять произвольный
JavaScript, что открывает доступ к теневым элементам.
Protractor поддерживает Jasmine и Mocha. Для больших веб-компонентов лучше использовать Page Object Model (POM).
Пример POM для веб-компонента:
class MyComponent {
constructor() {
this.shadowHost = element(by.tagName('my-component'));
}
async getShadowRoot() {
return await browser.executeScript('return arguments[0].shadowRoot', await this.shadowHost.getWebElement());
}
async clickButton() {
const shadowRoot = await this.getShadowRoot();
const button = await shadowRoot.findElement(By.css('button'));
await button.click();
}
async enterText(text) {
const shadowRoot = await this.getShadowRoot();
const input = await shadowRoot.findElement(By.css('input'));
await input.sendKeys(text);
}
async getLabelText() {
const shadowRoot = await this.getShadowRoot();
const label = await shadowRoot.findElement(By.css('.label'));
return await label.getText();
}
}
module.exports = MyComponent;
Использование POM позволяет абстрагировать детали Shadow DOM и упрощает поддержку тестов.
При работе с веб-компонентами часто возникают ошибки, связанные с недоступностью элементов. Для отладки полезно:
await browser.takeScreenshot().then((png) => {
const fs = require('fs');
fs.writeFileSync('screenshot.png', png, { encoding: 'base64' });
});
const logs = await browser.manage().logs().get('browser');
console.log(logs);
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
Эти инструменты помогают выявить проблемы с асинхронными компонентами и Shadow DOM.
Для автоматизации тестов веб-компонентов Protractor можно интегрировать с Jenkins, GitHub Actions или GitLab CI:
jobs:
e2e:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: 20
- run: npm install
- run: webdriver-manager update
- run: protractor protractor.conf.js
Тесты на веб-компонентах требуют стабильного браузера и корректной
настройки Shadow DOM. Параллельный запуск тестов можно настроить через
multiCapabilities в конфигурации Protractor.
Работа с веб-компонентами в Protractor требует внимания к Shadow DOM,
асинхронности и правильному использованию локаторов. Комбинация Page
Object Model, executeScript и
ExpectedConditions позволяет создавать надежные и
поддерживаемые тесты, пригодные для сложных фронтенд-приложений.