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

[Feature] Allow keyboard methods to be OS agnostic #12168

Closed
MartinP-Autopilot opened this issue Feb 17, 2022 · 6 comments · Fixed by #30572
Closed

[Feature] Allow keyboard methods to be OS agnostic #12168

MartinP-Autopilot opened this issue Feb 17, 2022 · 6 comments · Fixed by #30572

Comments

@MartinP-Autopilot
Copy link

This is the advice currently on https://playwright.dev/docs/api/class-keyboard

// on Windows and Linux
await page.keyboard.press('Control+A');
// on macOS
await page.keyboard.press('Meta+A');

The script should not have to implement special handling to ensure that these methods work in the expected manner across each OS, the method should allow something like

await page.keyboard.press('ControlOrMeta+A');

and the method should handle the OS detection transparently.

@MartinP-Autopilot
Copy link
Author

I just ran into something that should be taken into account when implementing this change - you can't just look at process.platform to figure out which key to use - we're now executing remotely to BrowserStack, running from linux on our CICD agent but the browser might be running on Mac or Windows - you need to query the browser -

async getBrowserOs(): Promise<string> {
    let OSName: string;
    let response: string = String(
      await this._page.evaluate(() => {
        return navigator.userAgent;
      })
    );
    if (response.indexOf('Win') != -1) OSName = 'Windows';
    if (response.indexOf('Mac') != -1) OSName = 'MacOS';
    if (response.indexOf('X11') != -1) OSName = 'Unix';
    if (response.indexOf('Linux') != -1) OSName = 'Linux';
    return OSName;
  }

@Nithos
Copy link

Nithos commented Jul 27, 2022

First of all, yes this would make the testing more seamless so +1 for this addition or similar.

As to your followup, I'm not sure if the browser check is correct as the commands might be coming from the OS. For instance I'm trying to copy some text then paste them back. To do the paste I use keyboard.press('${modifier}+KeyV') which depending on the userAgent will result in either Meta or Control.

Running this test on the 3 browsers (FF, Chromium, Webkit) the user agent returns Windows for FF and Chromium, and Mac for Webkit. So for FF and Chrome it will pick Control as the modifier, however running these tests locally on my Mac that is incorrect. It requires it to be Meta for all 3 cases as this is a System clipboard not a browser one.

So this may be further complicating how this could be implemented.

@canopy-js-user
Copy link

Did anyone find a workaround for this in the meantime? Thanks for making the original suggestion.

@nico-olivares
Copy link

nico-olivares commented Sep 9, 2022

This was my solution. It worked for me.

let macOS = process.platform === 'darwin' //darwin is macOS
let [newTab] = await Promise.all([
	context.waitForEvent('page'),
	macOS
		? link.click({ modifiers: ['Meta'] })
		: link.click({ modifiers: ['Control'] }),
])

@canopy-js-user
Copy link

Similar solution:

// before the tests

const os = require('os');
let platform = os.platform();
let systemNewTabKey;
if (platform === 'darwin') {
  systemNewTabKey = 'Meta';
} else {
  systemNewTabKey = 'Control';
}

// in the test

page.keyboard.press(`${systemNewTabKey}+Enter`)

@canbax
Copy link

canbax commented Feb 20, 2023

@nico-olivares @canopy-js-user aren't your answers fall into the trap @MartinP-Autopilot mentioned? His solution seems more robust IMHO. BTW @MartinP-Autopilot 's answer give false results on MacOS m1 chips in Playwright.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants