Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New API #76

Closed
wants to merge 34 commits into from
Closed

New API #76

wants to merge 34 commits into from

Conversation

mmarkelov
Copy link
Member

Thinking about rewriting jest-playwright with new API:
Using jest-playwright --parallel command is kind of hack, so I think about replacing it.

To run tests for specified browsers in you config you should do:
jest-playwright.config.js:

module.exports = {
    browsers: [ 'firefox', 'webkit', 'chromium'],
}

In tests:

describe('Google', () => {
    beforeAll(async () => {
       // It will navigate all browsers to url
        await page.goto('https://whatismybrowser.com/')
    })

    it('should display "google" text on page', async () => {
        const titles = await page.title()
        // Thinking about more clear and nice way to handle it
        titles.forEach(title => expect(title).toBe('What browser am I using? Is my browser up to date?'))
       // It will just return result for all browsers in array
        const [firefox, webkit, chrome] = await page.$eval('.string-major', el => el.innerHTML)

        expect(firefox).toContain('Firefox')
        expect(webkit).toContain('Safari')
        expect(chrome).toContain('Chrome')

    })
})

Let me know what do you think about it?

@mxschmitt
Copy link
Member

Thats a nice idea! So you are just replacing the implementation for multiple browsers as far as I've seen right?
Not fully sure about the const [firefox, webkit, chrome] part, maybe replace it with an object, because then it's easier to handle which key is associated with with browser by using object deconstruction.
Also your solution would mean in the end, that the user always have to check for N custom browsers which might be not so good for all the users and from the clean coding perspective.
But for every solution there are some disadvantages and when we compare this solution with the previous one, then this one is much nicer from my perspective.

@mmarkelov
Copy link
Member Author

@mxschmitt yeah! That is what I'm thinking about.
Replacing const [firefox, webkit, chrome] is a good idea, I suppose.
Yes, it will be not the cleanest way to do tests. But I think it is better way to tests multiple browsers.
Of cause this is not perfect, because of this:

    it('should display "google" text on page', async () => {
        const titles = await page.title()
        // That is not the best way
        titles.forEach(title => expect(title).toBe('What browser am I using? Is my browser up to date?'))
       // It will just return result for all browsers in array
        const {firefox, webkit, chrome} = await page.$eval('.string-major', el => el.innerHTML)
    })

I'm trying to improve it, but not sure that it will be possible to simplify it more

@mxschmitt
Copy link
Member

@mxschmitt yeah! That is what I'm thinking about.
Replacing const [firefox, webkit, chrome] is a good idea, I suppose.
Yes, it will be not the cleanest way to do tests. But I think it is better way to tests multiple browsers.
Of cause this is not perfect, because of this:

    it('should display "google" text on page', async () => {
        const titles = await page.title()
        // That is not the best way
        titles.forEach(title => expect(title).toBe('What browser am I using? Is my browser up to date?'))
       // It will just return result for all browsers in array
        const {firefox, webkit, chrome} = await page.$eval('.string-major', el => el.innerHTML)
    })

I'm trying to improve it, but not sure that it will be possible to simplify it more

One Idea would be to force the user that he needs to make

["chromium", "firefox", "webkit"].forEach(browserName => {
  const page = jestPlaywright.getBrowser(browserName)
  describe(`Testing browser ${browserName}`, () => {
    it("should do XYZ", async() => {
      
    })
  })
})

idk. Then reporting would also be kinda better afaik.

@mmarkelov
Copy link
Member Author

Some new thoughts here. I just added helper proxy to simplify test process:

describe('Google', () => {
  beforeAll(async () => {
    // It will navigate all browsers to url
    await page.goto('https://whatismybrowser.com/');
  });

  it('should display "google" text on page', async () => {
    const titles = await page.title();
    // It will expect toBe for all browsers

    // Passed tests
    expectAllBrowsers(titles).toBe('What browser am I using? Is my browser up to date?')

    // Failed tests
    const myBrowser = await page.$eval(
      '.string-major',
      el => el.innerHTML,
    );

    expectAllBrowsers(myBrowser).toContain('Chrome')
  });
});

I just think about nice error message here. For now it will be:

 FAIL  ./index.test.js (5.459s)
  Google
    ✕ should display "google" text on page (104ms)

  ● Google › should display "google" text on page

    expect(received).toContain(expected) // indexOf

    Expected substring: "Chrome"
    Received string:    "·······························
                                    <a href=\"/detect/what-version-of-firefox-do-i-have?utm_source=whatismybrowsercom&amp;utm_medium=internal&amp;utm_campaign=homepage&amp;utm_content=simple-major\">Firefox 73 on macOS (Catalina)</a>·······························
                    "

      18 |     );
      19 | 
    > 20 |     expectAllBrowsers(myBrowser).toContain('Chrome')
         |                                  ^
      21 |   });
      22 | });
      23 | 

      at browsers.forEach.browser (node_modules/jest-playwright-preset/lib/PlaywrightEnvironment.js:112:67)
          at Array.forEach (<anonymous>)
      at Proxy.toContain (node_modules/jest-playwright-preset/lib/PlaywrightEnvironment.js:107:34)
      at Object.it (index.test.js:20:34)

Failed test for firefox

@mxschmitt
Copy link
Member

cool! let's maybe ask the users who are actually using this feature what they think about that before we merge?

@mmarkelov
Copy link
Member Author

@mxschmitt yeah! I just want to support jest-playwright commands for some time. But I want to replace it with this one soon

@github-actions
Copy link

github-actions bot commented Apr 9, 2020

Pull Request Test Coverage Report for Build 47062a08620269e9ec26ff327fa6d35919c56745-PR-76

  • 0 of 0 changed or added relevant lines in 0 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage remained the same at 94.03%

Totals Coverage Status
Change from base Build 0be92af709e115b393e1653f103545baebfb9750: 0.0%
Covered Lines: 75
Relevant Lines: 76

💛 - Coveralls

@mmarkelov mmarkelov marked this pull request as ready for review April 9, 2020 16:43
@@ -1,6 +1,9 @@
/* eslint-disable no-console */
import NodeEnvironment from 'jest-environment-node'
import { Config as JestConfig } from '@jest/types'
import Expect = jest.Expect
import playwright, { Browser, BrowserContext, Page } from 'playwright'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please import types from playwright-core

@mmarkelov
Copy link
Member Author

Some updates here. Just tried to use it with jest-circus runner, it is ok. But for some reason it needs to run with forceExit and detectOpenHandles options. Still working on it

jest --forceExit --detectOpenHandles

@mxschmitt mxschmitt marked this pull request as draft April 16, 2020 17:13
@mmarkelov mmarkelov marked this pull request as ready for review April 17, 2020 07:17
…into New-API

� Conflicts:
�	src/PlaywrightEnvironment.ts
@mmarkelov mmarkelov marked this pull request as draft April 17, 2020 07:19
@mmarkelov
Copy link
Member Author

mmarkelov commented Apr 17, 2020

Some updates. I got passed tests on local machine. But got some issues with webkit. But for now it's quite working solution. I think it's better to use tests like so:

import path from 'path'

jest.setTimeout(10000)

describe('Example HTML file', () => {
  it('should detect the heading "Example" on page', async () => {
    await page.goto(`file:${path.join(__dirname, 'example.html')}`)
    const browser = await page.$eval('h1', (el) => el.textContent)
    expectAllBrowsers(browser).toBe('Example')
  })
})

Also I'm thinking about adding expectChromium and others for running expect function for specified browser. IDK how it will be relate to #96

@mxschmitt your thoughts?)

@@ -0,0 +1,4 @@
module.exports = {
USE_NEW_API: true,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why no camel case here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mxschmitt I think that snake style will show that it's experimental feature

@@ -1,16 +1,29 @@
/* eslint-disable no-console */
import NodeEnvironment from 'jest-environment-node'
import { Config as JestConfig } from '@jest/types'
import Expect = jest.Expect
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
import Expect = jest.Expect

const getResult = <T>(
data: T[],
instances: BrowserType[] | Array<keyof typeof playwright.devices>,
) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
) => {
): any => {

data: T[],
instances: BrowserType[] | Array<keyof typeof playwright.devices>,
) => {
const result: any = {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const result: any = {}
const result: any = {} // eslint-disable-line no-explicit-any

Copy link
Member

@mxschmitt mxschmitt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

small nits. Would be cool to clean the ESLint warnings and use pragmas for the any cases. Then we can merge in my mind.

@mxschmitt mxschmitt marked this pull request as ready for review April 17, 2020 10:04
@mmarkelov
Copy link
Member Author

small nits. Would be cool to clean the ESLint warnings and use pragmas for the any cases. Then we can merge in my mind.

Yeah! I agree but it seems challenging for me) To fix whole TS warnings

@mxschmitt
Copy link
Member

small nits. Would be cool to clean the ESLint warnings and use pragmas for the any cases. Then we can merge in my mind.

Yeah! I agree but it seems challenging for me) To fix whole TS warnings

Feel free to use // eslint-disable-line :)

@mmarkelov
Copy link
Member Author

I'll close it, cause I suppose using custom jest-runner is better solution for running tests for multiple browsers support
#113

@mmarkelov mmarkelov closed this May 7, 2020
@mxschmitt mxschmitt deleted the New-API branch June 15, 2020 08:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants