playwright icon indicating copy to clipboard operation
playwright copied to clipboard

[BUG] CapsLock doesn't work

Open nikolay-yavorovskiy opened this issue 2 years ago • 1 comments

Context:

  • Playwright Version: 1.24.2
  • Operating System: Win10
  • Node.js version: v.16.16
  • Browser: Chromium

Code Snippet

import { expect, test } from '@playwright/test'

test('Test CapsLock', async ({ page }) => {
  await page.goto('https://playwright.dev/')
  await page.locator('.DocSearch-Button-Placeholder').click()
  await page.keyboard.press('CapsLock')
  await page.keyboard.press('KeyA')
  await expect(page.locator('.DocSearch-Input')).toHaveValue('A') // actual value is 'a'
})

I was trying to write a test on the password input element which should show the warning message when the CapsLock button is turned on, but run into this issue. It's not a big deal and probably might be a bit painful to fix, but still...

nikolay-yavorovskiy avatar Aug 03 '22 17:08 nikolay-yavorovskiy

Is anyone here who can help me with pressing the "Dot" and "Delete" keys using playwright on mac? What exact string should I pass?

ShaneyWaris avatar Sep 18 '22 18:09 ShaneyWaris

Just ran into this issue as well trying to test a capslock warning on password fields.

xt0rted avatar Oct 21 '22 05:10 xt0rted

Everybody's gonna run into this issue trying to test caps lock warning on password field. 😄

kumarchandresh avatar Apr 02 '23 20:04 kumarchandresh

Everybody's gonna run into this issue trying to test caps lock warning on password field. 😄

Yep, same here.. :(

eternalconcert avatar Jan 17 '24 14:01 eternalconcert

I wanted to test CapsLock-related features in a JavaScript text editor -- visual feedback when CapsLock is on, different behavior of buttons for typing special characters. Currently seems impossible to do in Playwright.

tszynalski avatar Mar 29 '24 19:03 tszynalski

Hacked it using JavaScript! 💀

import { Locator, expect, test } from '@playwright/test'

async function pressKey(locator: Locator, key: string, modifiers: { CapsLock?: boolean } = {}) {
  await locator.evaluate((node, { key, modifiers }) => {
    function hacked(event: KeyboardEvent) {
      const _getModifierState = event.getModifierState
      return Object.assign(event, {
        getModifierState: function (key: string) {
          return key == 'CapsLock'
            ? modifiers.CapsLock
            : _getModifierState.call(this, key)
        },
      })
    }
    // Bubbling is needed for jQuery event handlers
    node.dispatchEvent(hacked(new KeyboardEvent('keyup', { key, bubbles: true })))
    node.dispatchEvent(hacked(new KeyboardEvent('keydown', { key, bubbles: true })))
    node.dispatchEvent(hacked(new KeyboardEvent('keypress', { key, bubbles: true })))
  }, { key, modifiers })
}

test('example', async ({ baseURL, page }) => {
  await page.goto(baseURL)
  for (const key of 'secret') {
    await pressKey(page.locator('#password'), key, { CapsLock: true })
  }
  await expect(page.locator('.caps-lock-on')).toBeVisible()
})

Best practice is to manage modifier states using a fixture.

kumarchandresh avatar Apr 03 '24 14:04 kumarchandresh

@kumarchandresh This works, thanks a lot! Now I can test CapsLock support. BTW, I think you could simply overwrite the .getModifierState method rather than constructing a new object with Object.assign().

tszynalski avatar Apr 08 '24 21:04 tszynalski