Protractor to Playwright.
Apply with the Grit CLI
grit apply protractor_to_playwright
Basic Sample
See: https://playwright.dev/docs/protractor
BEFORE
describe('angularjs homepage todo list', function () { it('should add a todo', function () { browser.get('https://angularjs.org'); element(by.model(module.sample)).sendKeys('first test'); element(by.model('todoList.todoText')).sendKeys('first test'); element(by.css('[value="add"]')).click(); var todoList = element.all(by.repeater('todo in todoList.todos')); expect(todoList.count()).toEqual(3); expect(todoList.get(2).getText()).toEqual('first test'); // You wrote your first test, cross it off the list todoList.get(2).element(by.css('input')).click(); var completedAmount = element.all(by.css('.done-true')); expect(completedAmount.count()).toEqual(2); }); });
AFTER
import { test, expect } from '@playwright/test'; test.describe('angularjs homepage todo list', function () { test('should add a todo', async function ({ page }) { await page.goto('https://angularjs.org'); await page.locator(`[ng-model="${module.sample}"]`).fill('first test'); await page.locator(`[ng-model="${'todoList.todoText'}"]`).fill('first test'); await page.locator('[value="add"]').click(); var todoList = page.locator(`[ng-repeat="${'todo in todoList.todos'}"]`); await expect(todoList).toHaveCount(3); await expect(todoList.nth(2)).toHaveText('first test'); // You wrote your first test, cross it off the list await todoList.nth(2).locator('input').click(); var completedAmount = page.locator('.done-true'); await expect(completedAmount).toHaveCount(2); }); });
Handle Async
BEFORE
var wait = function () { var EC = protractor.ExpectedConditions; browser.wait(EC.presenceOf($('#someId'))); browser.wait(EC.presenceOf($('#hello')), 1000); }; var two = () => { browser.wait(EC.presenceOf($('#someId'))); }; // Already sync var three = async () => { await browser.wait(EC.presenceOf($('#someId'))); };
AFTER
import { test, expect } from '@playwright/test'; var wait = async function () { await page.locator('#someId').waitFor({ state: 'attached' }); await page.locator('#hello').waitFor({ state: 'attached', timeout: 1000 }); }; var two = async () => { await page.locator('#someId').waitFor({ state: 'attached' }); }; // Already sync var three = async () => { await page.locator('#someId').waitFor({ state: 'attached' }); };
Avoid deleting code
BEFORE
async function attributeNotToMatch(selector, attr, text, { timeout } = {}) { let actual = ''; return browser.wait( async () => { actual = await attribute(selector, attr, { timeout }); return !doMatch(actual, text); }, utils.getTimeout(timeout), formatError({ selector, method: 'attributeNotToMatch', actual, expected: `not to match "${text}"`, }), ); }
AFTER
import { test, expect } from '@playwright/test'; async function attributeNotToMatch(selector, attr, text, { timeout } = {}) { let actual = ''; return page.waitForFunction( async () => { actual = await attribute(selector, attr, { timeout }); return !doMatch(actual, text); }, { timeout: utils.getTimeout(timeout) }, ); }
Does not modify unrelated files
JAVASCRIPT
function () { todoList.get(2).element(by.css('input')).click(); }