Command line tool that automatically migrates tests from protractor to playwright.

Overview

Protractor to Playwright migration tool

npm codecov

This tool is designed to automatically migrate code from Protractor to Playwright. It is inspired by the "Migrating from Protractor" guide in Playwright documentation.

Commands

The migration can be done directly by executing the following command in the e2e root folder:

npx @amadeus-it-group/protractor-to-playwright@latest --dst='relative/path/to/e2e-playwright-folder' --tsconfig='relative/path/to/tsconfig.conf.ts'

Basically, it takes these arguments:

  • cwd: Current directory to consider.Current directory by default,
  • src: Root folder of the e2e protractor tests. Current directory by default,
  • dst: Destination folder of the converted files. By default, the files are replaced at the same location,
  • tsconfig: tsconfig file, relative to the current directory. Whereas this parameter is not mandatory, it is advised to fill it if your e2e project is setup with a tsconfig.
  • file: optional glob pattern of the files to convert. By default '**/*.{ts, js}'.
  • test: optional parameter to convert the it keywords to test or test.step. You can prefer to use the steps if your successive tests in your files are not independant. It can take the following values:
    • test (default): 'it' are replaced by 'test', the {page} parameter is inserted and the setPage(page) is called at the first line to save the page globally.
    • step: 'it' are replaced by 'await test.step'. You will have to finish the conversion by wrapping your test.step in a test.

You can get the help on the usage with npx @amadeus-it-group/protractor-to-playwright@latest --help

Architecture

A file 'playwright-utils' is added at the root of destination folder. It contains useful functions to help the conversion.

In protractor, there is a notion of current page from where you can do actions. In Playwright, this page is given in the callback function parameter of a test. In order to reproduce the Protractor behaviour, the setPage function (of playwright-utils) must be used at the start of each test to store the current page, which can be retrieved at any time with the getPage function. The test object of playwright-utils must be used as well, in order to clear the current page at the end of the test.

Migration stategy

You can adopt different migration strategies depending on your project. This is an example of how it can be done:

  • Create a new branch for the migration,
  • Create the e2e-playwright folder, and setup a Playwright configuration.
  • Go to your project folder and open a command line,
  • Run npx @amadeus-it-group/protractor-to-playwright@latest --src=e2e --dst='e2e-playwright' --tsconfig='e2e/tsconfig.conf.ts' (e2e contains the protractor suite, e2e-playwright the folder for Playwright, e2e/tsconfig.conf.ts is the tsconfig for your protractor tests),
  • Check the results:
    • Check the console output (also saved in playwright-migration.log) to see some not transformed code.
    • Check the Typescript errors of the new files.
    • Check the work to be finished on your side (see the next section for more explanation).

The new code will not work directly and will require manual changes. At this point, either you detect that something can be improved in the tool, so you can contact us or open a PR, or the migration can be finished on your side in a reasonable time. At any time, you can use the 'file' parameter to migrate only a set of files.

At this point you can either wait for a new release with fixes or finish the work on your side (and you will not need the migration tool anymore :).

Code that will need a review/refactor by the application team

  • The test functions (replacement of 'it') are run with isolation, meaning that a new browser page is recreated for each test. After the conversion, you should check that:

    • beforeAll and afterAll would probably need to be converted in beforeEach and afterEach.

    • Your tests are independent. If it's not the case, they will need to be converted in 'test.step' inside a test (you can use the test parameter to convert them globally, if it's easier to finish the conversion).

      For example, after the migration, you can have:

          test('test 1', async({page}) => {
              ...
          });
      
          test('test 2', async({page}) => {
              // Test 2 depends on the actions done in test 1
              ...
          });

      As test 2 depends on test 1, you will need to convert the code this way:

          import { setPage } from "../../playwright-utils"; // Path to be adapted
          ...
          test('Global description', async ({page}) => {
              setPage(page);
      
              await test.step('test 1', async () => {
                  ...
              });
      
              await test.step('test 2', async () => {
                  // Test 2 depends on the actions done in test 1
                  ...
              });
          });
  • ElementArrayFinder.filter : This function returns a ElementArrayFinder, which can be chained with usual protractor methods. It will probably need to be refactored.

  • ExpectedConditions : even if a lot of these utility methods have been translated, the code would probably not need it and be refactored.

For example, in the following code:

    const button = this.page.locator('#buttonId');
    await browser.wait(ExpectedConditions.presenceOf(button));
    await button.click();

The line browser.wait is not needed at all, as Playwright provides all this waiting actions in the button.click.

Or:

    await browser.wait(ExpectedConditions.titleIs('My title'));

Must be replaced by:

    await expect(page).toHaveTitle('My title')
  • ExpectedConditions.alertIsPresent : alerts are managed with events in playwright. Need to be done differently.
  • ExpectedConditions.elementToBeClickable : usually useless, as Playwright manage it internally.
  • by.model(...) and by.repeater(...) are converted into [ng-model="..."] and [ng-repeat*="..."] selectors, but the logic in Protractor is more complex (see here for ng-model and here for ng-repeat). You'll have to adapt them if needed.

Found an issue?

This tool is designed to help the migration by doing as much as possible, but the migration may have to be completed manually.

If you detect a generic case which can be handled by the tool, don't hesitate to contact us. Some specific cases are project dependant, and must be managed by the project developers to finish the migration.

Comments
  • Not able to convert the file , destination folder is empty, also I want to try for converting js file , is there any option for that?

    Not able to convert the file , destination folder is empty, also I want to try for converting js file , is there any option for that?

    PS D:\Playrightconversions> npx @amadeus-it-group/protractor-to-playwright@latest --src=D:\Automation_Repository\ui-platform-automation --dst='D:\conversion' validateAttributeMessage-po.js step Start migration Apply 0 transformations Migration finished

    in my case, it is showing 0 migrations, let me know anything which I need to change here?

    opened by meghanagandhi-rs 8
  • Adding dependabot configuration

    Adding dependabot configuration

    The documentation is here: https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file

    opened by divdavem 4
  • Migrated code is using playwright-utils dependency which has been deprecated

    Migrated code is using playwright-utils dependency which has been deprecated

    Automation code having having locators in Protractor are being migrated as Protractor locator: var refreshButton = element(by.id('tci-list-header-refresh')); Migrated locator:
    var refreshButton = getPage().locator('.ng-app-list-name');

    getPage is a fixture of playwright-utils which has been deprecated https://www.npmjs.com/package/playwright-utils similarly all the browser.sleep or browser.wait() are converted into await getPage().waitForTimeout(3000) await waitCondition(ExpectedConditions.visibilityOf(appPage.uploadButton()), 5000, 'button not found');

    All the files have been added with this dependency import { getPage, ExpectedConditions, waitCondition } from "../../../playwright-utils";

    Do we have a workaround or fix for such conversions?

    opened by avndwivedi09 2
  • Fix incorrectly added

    Fix incorrectly added "await" when there is an assignment to a variable

    The following line:

    promise = $('.a').click();
    

    was incorrectly transformed into:

    await promise = page.locator('.a').click();
    

    This PR makes sure await is no longer added in that case:

    promise = page.locator('.a').click();
    
    opened by divdavem 2
  • Destination path is created along with converted file

    Destination path is created along with converted file

    When trying to convert .js files using npx @amadeus-it-group/protractor-to-playwrite@latest --file='xxx\xx\file.js' --dst='tests\xxx\xxx' We are getting converted file. js along with its original path created in the destination folder

    opened by suhasKaginkar 2
  • Not able to replace by.tagName('a'), by.css('.a') etc with playwright specific replacement

    Not able to replace by.tagName('a'), by.css('.a') etc with playwright specific replacement

    I am trying to convert one of the protractor test file to playwright. While doing so element gets replaced with page.locator but by.css('.a') doesn't get replaced with '.a' For eg. element(by.css("a[title='Sort']")).click() should get replaced with page.locator("a[title='Sort']").click(). Instead I am getting page.locator(by.css("a[title='Sort']")).click() This is one of the examples. The issue is same while replacing by.linkText('b'), by.cssContainingText('a', 'b'), by.id('a') etc with playwright specific replacements

    I'm attaching the the files both original and converted one in text format. Please look into it. Is there something I'm missing that leads to this issue? Kindly guide. original.spec.txt converted.spec.txt

    opened by Sourabhkelani 2
  • Replacement for clear().sendKeys(filterText)

    Replacement for clear().sendKeys(filterText)

    Hi, In Protrcator we have this mechanism to clear input and then add data Eg. element(by.css('[fisid="leftSearchFilter_1"]')).clear().sendKeys(filterText); While passing it through migration tool it gives below results getPage().locator('[fisid="leftSearchFilter_1"]').fill('').sendKeys(filterText); In playwright there is no concept of clear. If we want to clear and pass something, we can use fill directly. The above conversion should be as below await getPage().locator('[fisid="leftSearchFilter_1"]').fill((filterText); Note: await is also missing

    Can you please check and see is it possible to have this in script Thank You!

    opened by Sourabhkelani 0
  • Missing conversion for browser.actions

    Missing conversion for browser.actions

    browser.actions is not converted yet.

    Several actions can be chained and will finish by a perform() call. To convert them, we will need to split all these actions to several lines.

    The scope of the conversion will probably limited to the complete browser.actions. ... .perform() line, as it will be hard to manage, for example, a variable storing actions to perform it later...

    opened by fbasso 0
  • Simplify setPage usage

    Simplify setPage usage

    The idea is to see if we can find a way to simplify the setPage usage. At the moment, it is mandatory to set it at the start of each test.

    Some options:

    • add a beforeEach at the top of the spec file.
    • run the page fixture automatically (but it will prevent the api test from working without a page)
    opened by fbasso 2
Owner
Amadeus IT Group
The official global GitHub account of Amadeus IT Group. Amadeus provides the technology that keeps the travel sector moving.
Amadeus IT Group
🦄 A command line tool to get tokens on testnets quickly!

?? faucetli A command line tool to get tokens on testnets quickly! Usage Commands Usage $ npm install -g faucetli $ faucetli COMMAND running command..

Kira 60 Jan 1, 2023
A command-line tool to convert Project Zomboid map data into Deep Zoom format

pzmap2dzi pzmap2dzi is a command-line tool running on Windows to convert Project Zomboid map data into Deep Zoom format. Features Supports both python

Min Xiang 14 Dec 31, 2022
Command line tool that converts HTML to markdown.

@wcj/html-to-markdown HTML conversion tool to markdown. command line tool => @wcj/html-to-markdown-cli. Installation This package is ESM only: Node 14

小弟调调™ 11 Nov 6, 2022
📸 A command-line tool to generate code images of your local code right away from the terminal

?? rayli ?? A command-line tool to generate code images of your local code right away from the terminal Usage Commands Usage $ npm install -g rayli $

buidler's hub 45 Nov 4, 2022
🦄 A command line tool to get tokens on testnets quickly!

?? faucetli ?? A command line tool to get tokens on testnets quickly! Usage Commands Usage $ npm install -g faucetli $ faucetli COMMAND running comman

buidler's hub 56 May 11, 2022
Command line tool to interact with exist-db instances (pre-release)

xst [ĭg-zĭst′] Command line tool to interact with exist-db instances. Built on top of @existdb/node-exist. Installation Until this package is official

Juri Leino 0 Aug 4, 2022
A command-line tool to manage Deno scripts installed via deno install

??️ nublar nublar is a command-line tool to manage your scripts installed via deno install. ??️ Installation deno install --allow-read --allow-write -

Shun Ueda 16 Dec 26, 2022
Prismatic's CLI tool for managing prismatic.io resources from the command line

@prismatic-io/prism Prism is Prismatic's CLI tool that allows you to build, deploy, and support integrations in Prismatic from the comfort of your com

Prismatic.io 7 Oct 4, 2022
CloudCrafter CLI is a command-line interface tool that provides templates for common cloud resources to help you get started quickly.

CloudCrafter CLI CloudCrafter CLI is a command-line interface tool that provides templates for common cloud resources to help you get started quickly.

Missio 7 May 5, 2023
This is a test parser which can automatically parse the tests in from websites like codeforces, codechef, atcoder etc.

✔ Sublime test parser This is a test parser which can automatically parse the tests in from websites like codeforces, codechef, atcoder etc. See how i

Prakhar Rai 15 Aug 6, 2022
Diferentes demos em relação ao uso do Playwright para realização de palestras sobre o assunto

?? Playwright [Demos] - Palestra: Testes Inteligentes, Automatizados e Rápidos em Cross-Browser com Playwright! Repositório responsável pelas demos re

Glaucia Lemos 47 Oct 20, 2022
Google-reviews-crawler - A simple Playwright crawler that stores Google Maps Place/Business reviews to a JSON file.

google-reviews-crawler A simple Playwright crawler that stores Google Maps Place/Business reviews to a JSON file. Usage Clone the repo, install the de

￸A￸l￸e￸x D￸o￸m￸a￸k￸i￸d￸i￸s 6 Oct 26, 2022
Modern Cross Browser Testing in JavaScript using Playwright

Modern Cross Browser Testing in JavaScript using Playwright This repository contains the example code for the Modern Cross Browser Testing in JavaScri

Applitools 5 Oct 3, 2022
🚀 Macaca Playwright driver

macaca-playwright Playwright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API. Macaca P

Macaca 13 Nov 8, 2022
Remix + Cloudflare Workers + Wrangler2 + Tailwind + ESLint + Prettier + Vitest + Playwright

Welcome to Remix! Remix Docs Development You will be running two processes during development: The Miniflare server (miniflare is a local environment

null 48 Dec 19, 2022
Sample project to demonstrate Playwright Test usage, pointing to ServeRest API and Front-end

demo-playwright-test This is a sample project to demonstrate Playwright Test usage, running tests against ServeRest API and Front-end. Pre-requisites

Stefan Teixeira 30 Oct 24, 2022
Automagically bypass hcaptcha challenges with http api, with puppeteer, selenium, playwright browser automation scripts to bypass hCaptcha programmatically

Automagically bypass hcaptcha challenges with http api, with puppeteer, selenium, playwright browser automation scripts to bypass hCaptcha programmatically. For help you can message on discord server with the bellow link. You can also create an issue.

Shimul 199 Jan 2, 2023