Видео с гейзенбага 🪲
Выложили мой доклад с последнего heisenbug.
В прошлом году я рассказывал о проблемах перфоманса, а в весной сделал акцент на проблемы рендеринга. Всем любителям девтулзов и не равнодушным к веб-тестированию рекомендую к просмотру🖥
Теги: #heisenbug #доклад #tools
Выложили мой доклад с последнего heisenbug.
В прошлом году я рассказывал о проблемах перфоманса, а в весной сделал акцент на проблемы рендеринга. Всем любителям девтулзов и не равнодушным к веб-тестированию рекомендую к просмотру🖥
Теги: #heisenbug #доклад #tools
YouTube
Алексей Иванов — Браузерные инструменты: ищем проблемы рендеринга
Ближайшая конференция — Heisenbug 2025 Autumn, 19—20 октября, Санкт-Петербург + online. Подробности и билеты: https://jrg.su/D6uGC9
— —
Скачать презентацию с сайта Heisenbug — https://jrg.su/O4v5Fo
Глубокий технический анализ процессов веб-рендеринга, а…
— —
Скачать презентацию с сайта Heisenbug — https://jrg.su/O4v5Fo
Глубокий технический анализ процессов веб-рендеринга, а…
2👎63👍9❤3🔥3
Захват и анализ сетевого трафика через chrome://net-export. Это может быть полезно
chrome://net-export/ может предоставить более подробные данные, включая информацию о сетевых пакетах, DNS-запросах и внутренней работе браузера.В Chrome есть встроенная функция
net-export, которая проста и удобна в использовании:В итоге,
chrome://net-export/ чаще используется для более глубокого и продолжительного анализа сетевой активности, когда стандартных возможностей DevTools недостаточно для решения задач.Дальше открываешь полученный JSON netlog-viewer.appspot.com
Ставьте 👍👎
Теги: #chrome #netexport #devtools
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
1👎65👍13🤯4❤1
Forwarded from Грамота от Кузьмича
"Что лежит в его мерзких грязных карманцах?"
(с) Голлум, Властелин колец
Пороемся в карманах у браузера - где и что он хранит - и разберем cookies, sessionStorage & localStorage.
Про куки мы уже говорили в одном из постов выше. Вкратце - это небольшие файлы, которые сервер подкладывает в наш браузер что бы помнить кто ты, что ты, и какие настройки используешь. Куки отправляются сайту с каждым запросом к этому сайту.
📦localStorage - долгосрочное хранилище данных. Данные из localStorage доступны из любого окна/вкладки и хранятся до тех пор пока ты сам или веб приложение их не удалит. Т.е. localStorage похож на браузерный кеш - только хранит не скрипты, стили и картинки - а данные.
🖼Пример из жизни - Youtube хранит уровень громкости видео в localStorage (по ключу yt-player-volume), а раз localStorage доступен для всех вкладок и окон - то поэтому по умолчанию каждое новое открытое окно ютюба будет иметь одинаково выставленный уровень громкости.
🔒Доступ - через DevTools (вкладка Application) или через JS:
localStorage.setItem('имяКлюча', 'значение'); //запись
localStorage.getItem('имяКлюча'); //чтение📦sessionStorage - временное хранилище данных. Данные хранятся только пока ты находишься на конкретном сайте в конкретной вкладке. Как только ты покинешь сайт или закроешь вкладку - пиши пропало. Это типа буфера обмена, или временных заметок на полях для веб-приложений.
🖼Пример из жизни - Amazon при оформлении заказа может хранить данные из заполненных форм именно тут - что бы если пользаку после заполнения адреса доставки вдруг приспичило вернуться на предыдущий шаг - данные уже заполненного адреса не оказались потеряны. А Netflix - сохранит в sessionStorage текущую отметку времени просмотра видоса, так что при обновлении страницы ты не упадешь в самое начало серии а продолжишь просмотр оттуда где прервался. А еще с помощью sessionStorage запомнит что показывал те или иные рекомендации что бы не бесить по 10 раз подряд всплывашкой с рекомендацией одного и того же сериала.
🔒Доступ - через DevTools (вкладка Application) или через JS:
sessionStorage.setItem('имяКлюча', 'значение'); //запись
sessionStorage.getItem('имяКлюча'); //чтениеВ основе sessionStorage & localStorage так же как и у кук - лежит доменная модель. Т.е. каждому сайту - свой огород, свое пространство. Поэтому не удивляйся когда увидишь во вкладке дев тулов Local storage и Session storage по несколько хранилищ каждого из типов - каждый из сайтов будет иметь свое и в то же время не будет иметь доступа к "чужим" хранилищам, хранилищам других сайтов.
📦Для особо тяжелых (ресурсоемких) случаев - есть еще и IndexedDB - встроенная в браузер база данных (присутствует и в Chrome, и в Firefox, и в Safari). Там размер не фиксирован 5 или 10 мегабайтами и может достигать до 20% от свободного дискового пространства, а иногда и больше.
🖼Пример из жизни - та же гугл почта или гугл доки будут хранить копию данных в indexedDB, что позволит продолжить с ними работу даже при потере интернет-соединения. А при возврате коннекта - локально внесенные изменения в indexedDB тут же подтянутся на сервер, в облако.
___
P.S. огоньки🔥, сердечки❤️ и репосты📩 очень помогают каналу и заряжают мою батарейку на дальнейшее творчество и контент😉😇
2👎62👍19🔥15❤7
Локаторы vs селекторы🤓 💪
Что такое селекторы и локаторы в Playwright?
📌 Селекторы — это строки, которые используются для сопоставления элементов в DOM страницы. Playwright поддерживает различные типы селекторов, включая поиск по тексту, CSS, XPath и другие.
📌 Локаторы — это абстракция, построенная на основе селекторов, которая позволяет находить любые элементы на странице, а также обеспечивает "умные" ожидания, являющиеся ключевой функцией Playwright.
Я планирую написать подробное руководство о том, как и какой локатор лучше использовать. Вот выдержка из документации по рекомендуемым локаторам. Если ни одна из функций не подходит, можно добавить атрибут data-testid:
🔵
🔵
🔵
🔵
🔵
🔵
🔵
Было полезно? Ставьте👍 👎
Теги: #playwright
Что такое селекторы и локаторы в Playwright?
Я планирую написать подробное руководство о том, как и какой локатор лучше использовать. Вот выдержка из документации по рекомендуемым локаторам. Если ни одна из функций не подходит, можно добавить атрибут data-testid:
page.getByRole() для поиска по явным и неявным атрибутам доступности.page.getByText() для поиска по текстовому содержимому.page.getByLabel() для поиска по лейблуpage.getByPlaceholder() для поиска поля ввода по плейсхолдеру.page.getByAltText() для поиска элемента, по альтернативному тексту.page.getByTitle() для поиска элемента по его атрибуту noscript.page.getByTestId() для поиска элемента по атрибуту data-testid.Было полезно? Ставьте
Теги: #playwright
Please open Telegram to view this post
VIEW IN TELEGRAM
1👎64👍20❤2
Как сделать так, чтобы в ветку попадал только чистый и рабочий код?👩🍳
В разработке важно, чтобы в ветку попадал код, который соответствует стандартам и не ломает приложение или на код-ревью не писали💩 Один из эффективных способов это обеспечить — использование Git хуков, особенно
Для упрощения этого процесса есть масса различных библиотек📖 :
📍 husky (nodejs)
📍 pre-commit (python)
📍 использовать нативные (для любого проекта)
Пример настройки для nodejs husky📝
Прежде чем приступать к настройки у нас должны быть установлены linter, prettier
Пример package.json
Команда init упрощает настройку husky в проекте. Он создает
Дальше просто добавляем наши скрипты проверки качества кода
После можно попробовать сделать коммит и наши скрипты запустятся
Если вам надо закоммитить быстро можно отключить запуск хуков
Было полезно? Ставьте👍 👎
Теги: #husky #lint #prettier #git #commit
В разработке важно, чтобы в ветку попадал код, который соответствует стандартам и не ломает приложение или на код-ревью не писали
pre-commit. Этот хук запускает проверки до того, как изменения будут зафиксированы, и позволяет автоматизировать запуск линтера и тестов перед каждым коммитом.Для упрощения этого процесса есть масса различных библиотек
Пример настройки для nodejs husky
Прежде чем приступать к настройки у нас должны быть установлены linter, prettier
Пример package.json
{
"noscripts": {
"lint": "eslint .",
"format": "prettier . --write",
"test": "jest"
}
}Команда init упрощает настройку husky в проекте. Он создает
pre-commit в .husky/ и обновляет сценарий для подготовки в package.json.npx husky init
Дальше просто добавляем наши скрипты проверки качества кода
echo "npm prettier && npm lint && npm test" > .husky/pre-commit
После можно попробовать сделать коммит и наши скрипты запустятся
Если вам надо закоммитить быстро можно отключить запуск хуков
git commit -m "..." -n
Было полезно? Ставьте
Теги: #husky #lint #prettier #git #commit
Please open Telegram to view this post
VIEW IN TELEGRAM
1👎67👍15❤2🔥2
Меня читают много разработчиков и скорее всего это пост для них.
При написании юнит тестов возникает необходимость структурировать код таким образом, чтобы он был понятным, легко поддерживаемым и эффективно выявлял ошибки. Один из наиболее популярных подходов для достижения этих целей — паттерн AAA (Arrange-Act-Assert).
Патерн делит процесс написание тестов на 3 логические части:
Пример прям из тестов текущего проекта:
test('Закрывает Drawer при вызове onClose', () => {
// Arrange
render(<Comments />);
const closeButton = screen.getByRole('button', { name: 'close' });
// Act
fireEvent.click(closeButton);
TypeScript
// Assert
expect(mockedUseStore().services.comments.close).toHaveBeenCalled();
});Рекомендации
Почти все эти рекомендации можно соблюдать автоматически настроив правила
eslint-a с плагином eslint-plugin-jest.
Например:
test('Закрывает и открывает Drawer при вызове onClose', () => {
// Arrange
render(<Comments />);
const closeButton = screen.getByRole('button', { name: 'close' });
// Act
fireEvent.click(closeButton);
// Assert
expect(mockedUseStore().services.comments.close).toHaveBeenCalled();
// Arrange
const openCommentButton = screen.getByRole('button', { name: 'Комментарии' });
// Act
fireEvent.click(openCommentButton);
// Assert
expect(modal).toBeVisible();
});Тесты должны быть последовательны и без ветвлений.
Включите правило линтера: no-conditional-in-test.
Можно использовать правила линтера:
По мотивам книги Принципы юнит-тестирования
Теги: #unitTests #cleanСode #testing #TDD
Please open Telegram to view this post
VIEW IN TELEGRAM
1👎61👍8🔥4
Выход playwright 1.47
⚡ Обновления Playwright:
1⃣ Network Tab (небольшие улучшения в UI mode и trace viewer)
⚪ Фильтрация по типу запроса и URL
⚪ Улучшенное отображения query parameters
⚪ Превью для шрифтов
2⃣ Опция — tsconfig
Теперь можно указать конкретный tsconfig для всех импортируемых файлов:
3⃣ APIRequestContext
Поддержка URLSearchParams в query параметрах:
https://github.com/microsoft/playwright/releases/tag/v1.47.0
Теги: #playwright #updates
Теперь можно указать конкретный tsconfig для всех импортируемых файлов:
npx playwright test --tsconfig tsconfig.test.json
Поддержка URLSearchParams в query параметрах:
const response = await request.get('url', { params: 'userId=1' });https://github.com/microsoft/playwright/releases/tag/v1.47.0
Теги: #playwright #updates
Please open Telegram to view this post
VIEW IN TELEGRAM
GitHub
Release v1.47.0 · microsoft/playwright
Network Tab improvements
The Network tab in the UI mode and trace viewer has several nice improvements:
filtering by asset type and URL
better display of query string parameters
preview of font as...
The Network tab in the UI mode and trace viewer has several nice improvements:
filtering by asset type and URL
better display of query string parameters
preview of font as...
1👎63🔥13👍5❤3
Продолжаем тему с юнит тестами, и поговорим какие существуют антипаттерны при написании юнит тестов.
У вас есть класс
PaymentProcessor, который обрабатывает платежи и содержит приватный метод для валидации транзакций.class PaymentProcessor {
private validateTransaction(transaction: Transaction): boolean {
// сложная логика
return transaction.amount > 0 && transaction.currency === 'USD';
}
processPayment(transaction: Transaction): string {
if (this.validateTransaction(transaction)) {
return 'Payment processed';
} else {
return 'Invalid transaction';
}
}
}Антипаттерн:
Делаем метод публичным и тестирование метода
validateTransaction напрямую.Почему это плохо:
Тестировать публичный метод
processPayment, который использует приватный метод.Или провести рефакторинг и вынести
validateTransaction в отдельный класс.Класс
Inventory управляет списком товаров на складе.class Inventory {
private items: Item[] = [];
addItem(item: Item): void {
this.items.push(item);
}
getItems(): ReadonlyArray<Item> {
return this.items;
}
// Другие методы...
}Антипаттерн:
Чтобы упростить тестирование, приватное свойство
items делается публичным.Тестировать публичный метод
processPayment, который использует приватный метод.Система рассчитывает налог в зависимости от категории продукта.
class TaxCalculator {
calculateTax(product: Product): number {
if (product.category === 'Food') {
return product.price * 0.05;
} else if (product.category === 'Electronics') {
return product.price * 0.2;
}
return product.price * 0.1;
}
}Антипаттерн:
Тест дублирует бизнес-логику при расчете ожидаемого результата.
describe('TaxCalculator', () => {
it('should calculate tax for food category', () => {
const calculator = new TaxCalculator();
const product = { price: 100, category: 'Food' };
// тут дублируется логика
const expectedTax = product.price * 0.05;
const tax = calculator.calculateTax(product);
expect(tax).toBe(expectedTax);
});
});Почему это плохо:
Использовать конкретные значения для ожидаемых результатов.
describe('TaxCalculator', () => {
it('should calculate 5% tax for food category', () => {
const calculator = new TaxCalculator();
const product = { price: 100, category: 'Food' };
const tax = calculator.calculateTax(product);
expect(tax).toBe(5);
});
it('should calculate 20% tax for electronics category', () => {
const calculator = new TaxCalculator();
const product = { price: 200, category: 'Electronics' };
const tax = calculator.calculateTax(product);
expect(tax).toBe(40);
});
}); Теги: #unitTests #cleanСode #TDD #BDD #learning #recommendation #practices
Please open Telegram to view this post
VIEW IN TELEGRAM
👎58👍7❤3🔥2
Приложение отправляет уведомления пользователям через SMS.
class SmsService {
sendSms(number: string, message: string): void {
// Логика отправки SMS
}
}
class NotificationManager {
constructor(private smsService: SmsService) {}
notifyUser(user: User, message: string): void {
this.smsService.sendSms(user.phoneNumber, message);
}
}Антипаттерн:
В тестах мокируется конкретный класс
SmsService.describe('NotificationManager', () => {
it('should send SMS notification', () => {
const smsService = new SmsService();
spyOn(smsService, 'sendSms');
const manager = new NotificationManager(smsService);
manager.notifyUser({ phoneNumber: '1234567890' }, 'Test Message');
expect(smsService.sendSms).toHaveBeenCalledWith('1234567890', 'Test Message');
});
});Почему это плохо:
Использовать интерфейс для абстракции сервиса отправки сообщений.
interface IMessageService {
sendMessage(recipient: string, message: string): void;
}
class SmsService implements IMessageService {
sendMessage(recipient: string, message: string): void {
// Логика отправки SMS
}
}
class NotificationManager {
constructor(private messageService: IMessageService) {}
notifyUser(user: User, message: string): void {
this.messageService.sendMessage(user.phoneNumber, message);
}
}
🔎Тестирование с мокированием интерфейса:
describe('NotificationManager', () => {
it('should send message notification', () => {
const messageService: IMessageService = {
sendMessage: jasmine.createSpy('sendMessage'),
};
const manager = new NotificationManager(messageService);
manager.notifyUser({ phoneNumber: '1234567890' }, 'Test Message');
expect(messageService.sendMessage).toHaveBeenCalledWith('1234567890', 'Test Message');
});
});Стремитесь писать тесты, которые проверяют поведение через публичный интерфейс и фокусируются на результатах, а не на деталях реализации. Это сделает ваш код более надежным, а тесты — более ценными инструментами в процессе разработки.
Теги: #cleanСode #unitTests #TDD #BDD
Please open Telegram to view this post
VIEW IN TELEGRAM
4👎63👍12❤3
Декораторы в Playwrightт для мобильного тестирования📲
Нашел классную статью, где автор предлагает избавиться от дублирования кода и упростить поддержку тестов в Playwright. Как? С помощью декораторов TypeScript инкапсулировать платформенно-зависимую логику и создать единый тест для мобильных и настольных платформ.
Читать здесь📖
Теги: #playwright #cleanСode
Нашел классную статью, где автор предлагает избавиться от дублирования кода и упростить поддержку тестов в Playwright. Как? С помощью декораторов TypeScript инкапсулировать платформенно-зависимую логику и создать единый тест для мобильных и настольных платформ.
Читать здесь
Теги: #playwright #cleanСode
Please open Telegram to view this post
VIEW IN TELEGRAM
Medium
Mastering Mobile View Testing in Playwright: Simplify Your Workflow with TypeScript Decorators
When implementing mobile runs for E2E tests in Playwright, managing the workflow efficiently can be challenging:
4👎61👍9❤3
Тестирование с параметром noWaitAfter в Playwright🕐
Параметр
➡️
➡️
Сценарии использования:
💙 noWaitAfter: true в обработчиках локаторов
С версии Playwright 1.44 параметр
В этом примере обработчик кликает на кнопку закрытия оверлея, и благодаря
💙 noWaitAfter: false для получения данных
Когда требуется подождать завершения сетевого запроса, например, получения прогноза погоды, параметр
Здесь Playwright ждёт, пока данные полностью загрузятся, чтобы тест был надёжным.
💙 noWaitAfter: true для UI-манипуляций
Для операций, таких как переключение видимости элементов или обновление интерфейса, нет необходимости ждать завершения действий. Параметр
В этом тесте различные UI-операции выполняются без необходимости ждать завершения каждого действия, что ускоряет тест.
❓ Зачем использовать noWaitAfter?
➡️ Ускорение тестов. Пропуская ненужные ожидания, можно значительно повысить скорость выполнения тестов.
➡️ Обеспечение точности. Использование
⏰ Когда использовать noWaitAfter?
➡️ Используйте
➡️ Используйте
Теги: #playwright
Параметр
noWaitAfter в Playwright позволяет настроить, как обрабатываются действия, такие как клики по ссылкам, отправка форм или запуск сетевых запросов. Он определяет, должен ли Playwright ждать завершения вызванного события (навигации или перехода на другую страницу) перед тем, как перейти к следующему шагу.noWaitAfter: false (по умолчанию): Playwright ждёт завершения действия перед переходом к следующему шагу.noWaitAfter: true: Playwright немедленно переходит к следующему шагу, даже если действие ещё не завершено.Сценарии использования:
С версии Playwright 1.44 параметр
noWaitAfter: true можно использовать с обработчиками локаторов. Это особенно полезно при работе с оверлеями или другими элементами, которые могут мешать выполнению действий.test('Закрытие оверлея с noWaitAfter: true', async ({ page }) => {
await page.goto('http://localhost:3000');
// Локатор для оверлея
const overlayLocator = page.locator('#overlay');
// Добавляем обработчик локатора для закрытия оверлея
await page.addLocatorHandler(overlayLocator, async overlay => {
await overlay.locator('#closeButton').click(); // Закрытие оверлея
}, { times: 3, noWaitAfter: true }); // Макс. 3 раза, без ожидания после клика
// Взаимодействие с кнопкой после закрытия оверлея
await page.click('#fetchWeatherButton');
// Проверка отображения прогноза погоды
await page.waitForSelector('#weatherDisplay:has-text("Прогноз погоды для Chennai")');
});В этом примере обработчик кликает на кнопку закрытия оверлея, и благодаря
noWaitAfter: true, тест продолжает выполнение, не дожидаясь исчезновения оверлея.Когда требуется подождать завершения сетевого запроса, например, получения прогноза погоды, параметр
noWaitAfter: false гарантирует, что Playwright дождётся завершения запроса.test('Получение данных погоды с noWaitAfter: false', async ({ page }) => {
await page.goto('http://localhost:3000');
// Клик по кнопке "Получить прогноз погоды" и ожидание завершения запроса
await page.click('#fetchWeatherButton', { noWaitAfter: false });
// Проверка отображения данных после загрузки
await page.waitForSelector('#weatherDisplay:has-text("Прогноз погоды для Chennai")');
const weatherText = await page.textContent('#weatherDisplay');
console.log(weatherText);
});Здесь Playwright ждёт, пока данные полностью загрузятся, чтобы тест был надёжным.
Для операций, таких как переключение видимости элементов или обновление интерфейса, нет необходимости ждать завершения действий. Параметр
noWaitAfter: true позволяет пропускать лишние ожидания.test('UI-манипуляции с noWaitAfter: true', async ({ page }) => {
await page.goto('http://localhost:3000');
// Клик по кнопке без ожидания
await page.click('#toggleButton', { noWaitAfter: true });
await page.waitForSelector('#toggleElement.visible');
// Симуляция быстрых кликов без ожидания
await page.click('.rapidButton', { noWaitAfter: true });
// Кастомное действие, активируемое таймером
await page.click('#customActionButton', { noWaitAfter: true });
await page.waitForSelector('#customActionResult:has-text("Действие завершено!")');
});В этом тесте различные UI-операции выполняются без необходимости ждать завершения каждого действия, что ускоряет тест.
noWaitAfter: false гарантирует, что Playwright будет ждать завершения действий, требующих сетевых запросов или навигации, что снижает риск ложноположительных результатов. noWaitAfter: false для действий, связанных с навигацией или загрузкой данных.noWaitAfter: true для манипуляций с интерфейсом и других действий, не требующих ожидания.Теги: #playwright
Please open Telegram to view this post
VIEW IN TELEGRAM
2👎58👍6❤4🔥3
Правильное использование
noWaitAfter помогает создавать быстрые и надёжные тесты, оптимизируя время ожидания в зависимости от типа действия.Источник
Было полезно? Ставьте
Теги: #playwright #tools #testing
Please open Telegram to view this post
VIEW IN TELEGRAM
2👎61👍10❤5🔥3
Автоматизация тестирования:
#automation
#playwright
#cypress
#selenium
Инструменты:
#tools
#postman
#k6
#grafana
Процессы тестирования:
#process
#agile
#TDD
#BDD
Обучение и рекомендации:
#learning
#recommendation
#books
Практики:
#practices
#cleanСode
#unitTests
Общие темы и тренды:
#trends
#updates
#ai
#automation
#playwright
#cypress
#selenium
Инструменты:
#tools
#postman
#k6
#grafana
Процессы тестирования:
#process
#agile
#TDD
#BDD
Обучение и рекомендации:
#learning
#recommendation
#books
Практики:
#practices
#cleanСode
#unitTests
Общие темы и тренды:
#trends
#updates
#ai
1👎60❤10👍5🔥5
Архитектура playwright🏠
Когда ты работаешь с инструментом важно исследовать его внутренности и понимать как он работает
Давайте разберем playwright
Корневая директория📝
В корневой директории мы находим следующие папки:
🌸
🌸
🌸
🌸
🌸
🌸
🌸
А также файл
Файл👇
✳️
✳️
✳️
✳️
✳️
Директория packages✏️
Директория
Пакеты для отчётности и генерации тестов
Playwright содержит множество различных пакетов для отчётности о тестах, каждый со своим набором функций. Кратко, список пакетов в этой категории:
✳️
✳️
✳️
✳️
✳️
Эти пакеты содержат код, связанный с обработкой отчётов о тестах или их генерацией с помощью пакета
Пакеты, специализированные для браузеров
Каждый из этих пакетов просто экспортирует пакет
✳️
✳️
✳️
Пакеты для установки браузеров
Эти пакеты включают только скрипты установки для каждого из браузеров. Например, playwright-browser-chromium соответствует пакету @playwright/browser-chromium на npmjs.
✳️
✳️
✳️
Пакеты для тестирования компонентов
Эти пакеты связаны с экспериментальной системой тестирования компонентов в Playwright. Они предоставляют функциональность, аналогичную тому, как Jest может рендерить отдельные компоненты для разных библиотек.
✳️
✳️
✳️
✳️
✳️
✳️
✳️
Когда ты работаешь с инструментом важно исследовать его внутренности и понимать как он работает
Давайте разберем playwright
Корневая директория
В корневой директории мы находим следующие папки:
playwright/browser_patches/docs/examples/packages/tests/utils/А также файл
package.json, который включает следующие ключи:{
"name": "playwright-internal",
"private": true,
"workspaces": ["packages/*"]
}Файл
package.json намекает, что основная функциональность находится внутри директории packages/, поскольку корневой файл помечен как private, имеет в названии "internal" и использует ключ "workspaces", который сообщает Node.js, что проект имеет несколько пакетов. Давайте быстро рассмотрим другие директории верхнего уровня перед тем, как углубиться в папку packages/browser_patches — эта папка содержит патчи для браузеров, добавляющие дополнительные элементы управления и функции к некоторым движкам браузеров, используемых в этом проекте. Интересно, что здесь есть патч для WebKit, позволяющий ему работать на Windows.docs — папка docs содержит файлы Markdown, которые компилируются в документацию, представленную на сайте Playwright.examples — здесь находятся примеры тестовых скриптов, к которым можно обратиться при начале работы с проектом Playwright.tests — даже библиотеки для тестирования должны иметь автоматизированные тесты, которые написаны с использованием Playwright.utils — директория utils содержит различные инструменты, используемые во время сборки, Docker-образы, функциональность для Azure, генератор файлов типов и многое другое.Директория packages
Директория
packages содержит более 20 отдельных пакетов, что усложняет понимание. Мы разделим этот список на понятные категории.Пакеты для отчётности и генерации тестов
Playwright содержит множество различных пакетов для отчётности о тестах, каждый со своим набором функций. Кратко, список пакетов в этой категории:
html-reporter/recorder/trace-viewer/trace/web/Эти пакеты содержат код, связанный с обработкой отчётов о тестах или их генерацией с помощью пакета
recorder. Кроме того, есть trace и trace-viewer, которые могут записываться во время выполнения тестов Playwright. Пакет web/ предоставляет утилиты, общие для различных веб-инструментов, перечисленных здесь.Пакеты, специализированные для браузеров
Каждый из этих пакетов просто экспортирует пакет
playwright-core вместе со скриптом установки только для соответствующего браузера. Вы можете найти их на npmjs, например, playwright-chromium — это отдельный пакет, который имеет Playwright, специализированный только для автоматизации Chromium.playwright-chromium/playwright-firefox/playwright-webkit/Пакеты для установки браузеров
Эти пакеты включают только скрипты установки для каждого из браузеров. Например, playwright-browser-chromium соответствует пакету @playwright/browser-chromium на npmjs.
playwright-browser-chromium/playwright-browser-firefox/playwright-browser-webkit/Пакеты для тестирования компонентов
Эти пакеты связаны с экспериментальной системой тестирования компонентов в Playwright. Они предоставляют функциональность, аналогичную тому, как Jest может рендерить отдельные компоненты для разных библиотек.
playwright-ct-core/playwright-ct-react/playwright-ct-react17/playwright-ct-solid/playwright-ct-svelte/playwright-ct-vue/playwright-ct-vue2/Please open Telegram to view this post
VIEW IN TELEGRAM
👎61👍7🔥5❤2
Основные функциональные пакеты
Наконец, мы подходим к основным пакетам #Playwright, которые содержат всю главную функциональность проекта.
✳️
✳️
✳️
✳️
Обратите внимание, что папка
Другой пакет, на который стоит обратить внимание, — это
Теперь два основных пакета всей библиотеки Playwright — это
В этом случае вы, вероятно, импортируете код из пакета
Другой основной пакет —
С другой стороны, клиентская библиотека содержит все пользовательские API, которые вы используете при написании скриптов автоматизации браузера. Например, если у вас есть такой скрипт:
Вы фактически импортируете
Затем вызовы
Такой принцип разделения ответственности работает хорошо, потому что позволяет поддерживать несколько языков, которые могут использовать API автоматизации браузера Playwright. Фактически, если вы посмотрите на другие реализации библиотеки Playwright, вы обнаружите те же шаблоны проектирования (например,
Перевод
Еще интересные статьи про архитектуру playwright:
➡️ https://qacomet.com/playwright/how-playwright-initializes/
➡️ https://medium.com/@divyarajsinhdev/understanding-playwright-architecture-e456fcee0222
Полезно? Ставьте👍 👎
Наконец, мы подходим к основным пакетам #Playwright, которые содержат всю главную функциональность проекта.
playwright-core/playwright-test/playwright/protocol/Обратите внимание, что папка
playwright-test — это просто обёртка для связывания playwright-core и playwright вместе в пакете @playwright/test, устанавливаемом через npm. Если вы посмотрите в файл index.js, вы увидите только экспорт из playwright/test, который находится в пакете playwright.Другой пакет, на который стоит обратить внимание, — это
protocol, который содержит автоматически сгенерированный код через некоторые скрипты сборки в директории utils корневой директории проекта Playwright. Он содержит YAML-файл protocol.yml, который перечисляет все интерфейсы, используемые протоколом Playwright. Если вы когда-либо захотите создать драйвер для Playwright на другом языке, это один из основных файлов, к которому стоит обратиться при создании этой библиотеки.Теперь два основных пакета всей библиотеки Playwright — это
playwright и playwright-core. Первый из них является обёрткой вокруг playwright-core и отвечает за управление всей логикой тестирования. Это включает запуск рабочих процессов тестирования, выполнение тестов, отчёты о результатах, управление повторными запусками и утверждениями тестов. Хорошим ориентиром для кода, содержащегося в этом пакете, является любая конфигурационная логика, которую вы найдёте в файле playwright.config.ts, или любой связанный с запуском тестов код, например:// my-test.spec.ts
import { test } from "@playwright/test";
В этом случае вы, вероятно, импортируете код из пакета
playwright.Другой основной пакет —
playwright-core, который содержит всю функциональность автоматизации браузера. Эта функциональность разделена на два основных компонента: клиентскую библиотеку и серверную библиотеку. Серверная библиотека, находящаяся в packages/playwright-core/src/server, содержит всю логику, отвечающую за действия автоматизации браузера. Это означает, что она отправляет команды через Chrome DevTools Protocol (CDP) или аналогичные протоколы, чтобы сообщить браузеру выполнить такие действия, как "нажать кнопку входа", "ввести 'Hello' в текстовое поле" или "перейти на 'https://news.ycombinator.com'". Серверная библиотека содержит реализации для каждого из поддерживаемых браузеров и предоставляет унифицированный API через WebSocket-сервер для доступа к этой функциональности из других процессов.С другой стороны, клиентская библиотека содержит все пользовательские API, которые вы используете при написании скриптов автоматизации браузера. Например, если у вас есть такой скрипт:
// my-automation-noscript.ts
import { chromium } from "@playwright/test";
(async function () {
const browser = await chromium.launch({ headless: false });
const page = await browser.newPage();
await page.goto("https://playwright.dev");
})();
Вы фактически импортируете
chromium из экземпляра класса в playwright-core/client/playwright. Затем вызовы
browser.newPage и page.goto делают запросы к интерфейсам в серверной библиотеке, которая взаимодействует с браузерами через CDP или аналогичные протоколы. Это означает, что если вы когда-либо захотите написать собственный инструмент автоматизации браузера, независимый от конкретного браузера, полезной отправной точкой будет использование серверной библиотеки из пакета playwright-core, поскольку она предоставляет всесторонний и проверенный API для такой функциональности.Такой принцип разделения ответственности работает хорошо, потому что позволяет поддерживать несколько языков, которые могут использовать API автоматизации браузера Playwright. Фактически, если вы посмотрите на другие реализации библиотеки Playwright, вы обнаружите те же шаблоны проектирования (например,
ChannelOwner), что и в клиентской библиотеке, найденной в playwright-core.Перевод
Еще интересные статьи про архитектуру playwright:
Полезно? Ставьте
Please open Telegram to view this post
VIEW IN TELEGRAM
QAComet
QAComet | Architecture of Playwright
Let's dive into Playwright's internals by looking at how the project is structured and discover it's essential components.
👎56🔥10❤9👍4🤯1
Октябрь и ноябрь выдался на события
Прямо на конференции получил новость о том, что мою должность сокращают
Планы на оставшийся ноябрь также грандиозные:
Какие темы было бы интересно поднять?
#breakingnews
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegram
MoscowQA
📚Moscow QA приглашает всех на обсуждение книги "Принципы юнит-тестирования" Владимира Хорикова!
На встрече обсудим 1-3 главы книги, погрузимся в основы юнит-тестирования и разберем ключевые идеи автора. Будет интересно и полезно как новичкам, так и seniorам.…
На встрече обсудим 1-3 главы книги, погрузимся в основы юнит-тестирования и разберем ключевые идеи автора. Будет интересно и полезно как новичкам, так и seniorам.…
👎55🔥10❤4👍4
Сходили с женой на небольшое интервью, очень интересный и необычный опыт
https://youtu.be/bZzAbHWYjrw
https://youtu.be/bZzAbHWYjrw
YouTube
Путь В Профессию QA | Как Построить Карьеру В QA | Интервью С Основателями MoscowQA
Участвуй в розыгрыше трех Mystery Box от "IT всему голова" & MoscowQA
Условия розыгрыша:
49:26 розыгрыш
Подпишись на YouTube "IT всему голова"
Перейди по ссылке: t.me/ITheadeverything и нажми "Участвовать"
Подпишись на наш TG-канал: t.me/ITheadeverything…
Условия розыгрыша:
49:26 розыгрыш
Подпишись на YouTube "IT всему голова"
Перейди по ссылке: t.me/ITheadeverything и нажми "Участвовать"
Подпишись на наш TG-канал: t.me/ITheadeverything…
2👎58🔥16👍7❤2
Ох, раньше я обожал собеседования…🗣
Но после того, как за последний месяц прошел их столько, что уже голова кругом, чувствую, что хватит. Поэтому решил: будет много разборов вопросов с собеседований, но не в формате «вопрос-ответ». Я готовлю небольшие статьи, где в одном тексте отвечаю сразу на 2-3 популярных вопроса.
Например:
✅ Что такое браузерный движок и зачем он нужен?
✅ Какие браузерные движки существуют?
✅ Основные этапы рендеринга страницы?
✅ Как работает JavaScript в браузере?
✅ Какие движки JavaScript существуют?
✅ В чем разница между браузерным движком и JavaScript движком?
В браузере есть два ключевых компонента:
❗️ Браузерный движок (Rendering Engine)
❗️ Движок JavaScript (JavaScript Engine)
🌐 Браузерный движок
«Мозг» браузера, который превращает HTML и CSS в красивую картинку на экране.
Его этапы работы:
🟡 Парсинг HTML и CSS (dom и cssom)
🟡 Создание рендер-дерева
🟡 Компоновка (layout)
🟡 Отрисовка (painting)
🟡 Выделение слоев (compositing)
Примеры движков:
🟡 Blink (Chrome, Edge, Opera, Яндекс.Браузер)
🟡 Gecko (Firefox)
📶 Движок JavaScript
Отвечает за выполнение JS-кода, включая парсинг и оптимизацию.
Примеры движков:
🔵 V8 (Google Chrome, Microsoft Edge)
🔵 SpiderMonkey (Mozilla Firefox)
🔵 JavaScriptCore (Nitro) (Safari)
Основные этапы работы (на примере V8):
1️⃣ Парсинг: создание AST (Abstract Syntax Tree).
2️⃣ Генерация байт-кода: промежуточное представление, которое проще
интерпретировать.
3️⃣ Интерпретация: выполнение байт-кода.
4️⃣ JIT-компиляция: профилирование и компиляция часто вызываемого кода в машинный.
🟣 Если движок обнаруживает, что какой-то участок кода исполняется часто, он компилирует его в машинный код.
🟣 Используется профилирование выполнения (например, частота вызова функций или типы переменных).
Подробнее о том как работает v8 смотрите➡️ на Хабре.
Но после того, как за последний месяц прошел их столько, что уже голова кругом, чувствую, что хватит. Поэтому решил: будет много разборов вопросов с собеседований, но не в формате «вопрос-ответ». Я готовлю небольшие статьи, где в одном тексте отвечаю сразу на 2-3 популярных вопроса.
Например:
В браузере есть два ключевых компонента:
«Мозг» браузера, который превращает HTML и CSS в красивую картинку на экране.
Его этапы работы:
Примеры движков:
Отвечает за выполнение JS-кода, включая парсинг и оптимизацию.
Примеры движков:
Основные этапы работы (на примере V8):
интерпретировать.
Подробнее о том как работает v8 смотрите
Please open Telegram to view this post
VIEW IN TELEGRAM
Хабр
Как работает JS: о внутреннем устройстве V8 и оптимизации кода
[Советуем почитать] Другие 19 частей цикла Часть 1: Обзор движка, механизмов времени выполнения, стека вызовов Часть 2: О внутреннем устройстве V8 и оптимизации кода Часть 3: Управление памятью,...
3👎55❤28👍17🔥7
Forwarded from Артём Ерошенко | Тестируем с умом
Allure 3 теперь в открытом доступе! 🎉
Мы сделали Allure 3 полностью открытым. Заглядывайте в репозиторий, ставьте звёздочку ⭐️ и пробуйте всё самостоятельно!
Подключить Allure 3 в проект — дело пары секунд:
В Allure 2 мы сделали универсальный отчёт со множеством вкладок. Со временем он стал перегружен: не все возможности требовались пользователям. В Allure 3 мы пошли другим путём: каждый отчёт заточен под конкретную задачу 🎯, чтобы вы выбирали только нужные функции.
🏆 Классический отчёт
Это знакомый всем отчёт из Allure 2 — со вкладками, графиками, таймлайном и остальной аналитикой. Обратной совместимости с плагинами нет, но мы над ними думаем. Если вам по душе классический отчет — этот вариант для вас.
💎 Awesome отчёт
Минималистичный дизайн, тёмная тема и свежий взгляд на результаты. Ничего лишнего — всё по делу. Отличный выбор для тех, кто ценит современный, сдержанный стиль.
📟 Консольный лог
В Allure 2 мы сделали универсальный HTML-отчёт для автотестов, а сейчас расширили идею ещё дальше: консольный лог — это единый формат для CI/CD, без привязки к конкретному фреймворку.
И это только начало! 🚀 Allure 3 умеет выдавать отчёты в реальном времени, автоматически перезапускать тесты, отправлять уведомления в Slack и работать с Quality Gates. Мы расскажем про эти фичи подробнее в следующих постах.
Пробуйте, интегрируйте, делитесь впечатлениями и не забудьте отправить 🤙 этот пост коллегам.
Мы сделали Allure 3 полностью открытым. Заглядывайте в репозиторий, ставьте звёздочку ⭐️ и пробуйте всё самостоятельно!
Подключить Allure 3 в проект — дело пары секунд:
npm add allure
yarn add allure
pnpm add allure
В Allure 2 мы сделали универсальный отчёт со множеством вкладок. Со временем он стал перегружен: не все возможности требовались пользователям. В Allure 3 мы пошли другим путём: каждый отчёт заточен под конкретную задачу 🎯, чтобы вы выбирали только нужные функции.
🏆 Классический отчёт
Это знакомый всем отчёт из Allure 2 — со вкладками, графиками, таймлайном и остальной аналитикой. Обратной совместимости с плагинами нет, но мы над ними думаем. Если вам по душе классический отчет — этот вариант для вас.
npx allure classic path/to/allure-results --single-file
💎 Awesome отчёт
Минималистичный дизайн, тёмная тема и свежий взгляд на результаты. Ничего лишнего — всё по делу. Отличный выбор для тех, кто ценит современный, сдержанный стиль.
npx allure awesome path/to/allure-results --single-file
📟 Консольный лог
В Allure 2 мы сделали универсальный HTML-отчёт для автотестов, а сейчас расширили идею ещё дальше: консольный лог — это единый формат для CI/CD, без привязки к конкретному фреймворку.
npx allure log path/to/allure-results
И это только начало! 🚀 Allure 3 умеет выдавать отчёты в реальном времени, автоматически перезапускать тесты, отправлять уведомления в Slack и работать с Quality Gates. Мы расскажем про эти фичи подробнее в следующих постах.
Пробуйте, интегрируйте, делитесь впечатлениями и не забудьте отправить 🤙 этот пост коллегам.
👎57👍21🔥2
Фремворк vs библиотека 🙌
В чем разница между библиотекой и фреймворком?👀
Если коротко и просто👇
📌 Библиотека — это набор инструментов, функций или классов, которые вы сами подключаете и вызываете в своём коде, когда это нужно. Вы полностью управляете процессом и решаете, как именно эти инструменты использовать.
📌 Фреймворк — это уже целая структура, которая задаёт правила и порядок работы. Вы добавляете свой код внутрь этой структуры, но основная логика и жизненный цикл уже управляются фреймворком.
Представьте стройку🔨
🛠 Библиотека — это как набор инструментов: молоток, пила, шуруповёрт. Вы решаете, какие из них и когда использовать.
🏠 Фреймворк — это как готовый каркас дома. Вам остаётся добавить окна, двери и мебель, но основные правила и процесс строительства уже заданы.
Playwright как пример:
Playwright сам по себе — это библиотека. Он предоставляет API для управления браузерами (запуск, навигация по страницам, работа с элементами). Вы решаете, как и где его использовать, а сам Playwright не навязывает структуру.
Playwright Test — это уже фреймворк. Он добавляет тестовый раннер, готовый жизненный цикл тестов, параллельный запуск, ассерты и отчёты. С ним вам не нужно думать о базовой организации тестов — фреймворк берёт это на себя.
Ключевое различие👇
В библиотеке вы управляете всем сами. В фреймворке — вы следуете его правилам и структуре.
Какие еще примеры библиотеки/фреймворка знаете?🤔
В чем разница между библиотекой и фреймворком?
Если коротко и просто
Представьте стройку
Playwright как пример:
Playwright сам по себе — это библиотека. Он предоставляет API для управления браузерами (запуск, навигация по страницам, работа с элементами). Вы решаете, как и где его использовать, а сам Playwright не навязывает структуру.
Playwright Test — это уже фреймворк. Он добавляет тестовый раннер, готовый жизненный цикл тестов, параллельный запуск, ассерты и отчёты. С ним вам не нужно думать о базовой организации тестов — фреймворк берёт это на себя.
Ключевое различие
В библиотеке вы управляете всем сами. В фреймворке — вы следуете его правилам и структуре.
Какие еще примеры библиотеки/фреймворка знаете?
Please open Telegram to view this post
VIEW IN TELEGRAM
👎65🔥13❤7👍2