-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
[BUG] Error: locator.isVisible: SyntaxError: Invalid flags supplied to RegExp constructor ' >> internal:role=button' #26974
Comments
Objects that you pass are equivalent, so I'm not sure what it going on there - note that your snippets are missing closing brackets. Anyhow, following works fine: test('regex', async ({ page }) => {
const text = "Engineer's Log"
await expect(page.locator('div').filter({ hasText: new RegExp(`^${text}$`) })).toBeHidden();
await expect(page.locator('div').filter({ hasText: /^Engineer's Log$/ })).toBeHidden();
}); I'm not sure what |
No, nothing custom just a reference to an existing locator. We use POMs for specific components too not just entire pages, so this is a for a Tree component as mentioned. export abstract class AbstractPOM {
readonly locator: Locator
constructor(locator: Locator) {
this.locator = locator
}
}
export class TreePOM extends AbstractPOM {
getNode(text: RegExp | string): TreeNodePOM {
return new TreeNodePOM(
this.locator.locator('div').filter({ hasText: isString(text) ? new RegExp(`^${text}$`) : text })
)
}
} That's all, the locator logic is 100% Playwright. I normally have a loop that finds/expands tree nodes from string/regexp but for simplicity I broke this down (the test would fail because I'm looking for engineer's log in two places but I am seeing the regex get manipulated by playwright related to the error above. However, this doesn't trigger the error yet the text input is exactly the same... so I don't know where the breakdown is. const treeNode = new TreePOM(page.locator('_react=Tree')).getNode("Engineer's Log")
const text = "Engineer's Log"
await expect(treeNode.locator.locator('div').filter({ hasText: new RegExp(`^${text}$`) })).toBeVisible() For some reason in this case, playwright is escaping the regex differently:
I even modified my getNode function to hard-code the regex example: getNode(text: RegExp | string): TreeNodePOM {
let regex = new RegExp(`^${text}$`)
if (typeof text !== 'string') {
text = "Engineer's Log"
regex = new RegExp(`^${text}$`)
}
return new TreeNodePOM(this.locator.locator('div').filter({ hasText: regex }))
} Here's the loop code I use that triggers the error, but it's still just passing a string of "Engineer's Log" to the same getNode/regex code above. export class SubmodulePOM {
readonly page: Page
readonly navigationTree: TreePOM
private readonly path: string
/**
* Constructor
*
* @param page - The page object
* @param path - The url path
*/
constructor(page: Page, path: string, mainGridLocator = '_react=MainGrid') {
this.page = page
this.path = path
this.navigationTree = new TreePOM(this.page.locator('_react=Tree'))
}
async goto(): Promise<void> {
await this.page.goto(this.path)
}
async navigateViaTree(nodes: ReadonlyArray<RegExp | string> = []): Promise<void> {
for (const node of nodes) {
const treeNode = this.navigationTree.getNode(node)
// We use await inside a loop because these must be synchronous
/* eslint-disable no-await-in-loop */
await treeNode.isVisible()
const isLeaf = await treeNode.isLeaf()
await (isLeaf ? treeNode.select() : treeNode.toggle())
/* eslint-enable no-await-in-loop */
}
}
} Then in my test I'd use: const textLogs = new TextLogsPOM(page)
await textLogs.goto()
// Expand tree nodes and select a leaf to load data into the main grid
await textLogs.navigateViaTree(['USNS Evers', 'Engine', new RegExp("^Engineer's Log$")]) // this breaks the regex too |
Ok, narrowed down further. The regex error occurs when I expand tree nodes in loop, but it does not occur when I expand each node by itself, even though my regex is exactly the same. I ditched all of our POMs and made the most basic example I can. test.describe('text logs', () => {
test('regex', async ({ page }) => {
await page.goto('text-logs')
const treeLocator = page.locator('_react=Tree')
const nodes = ['USNS Evers', 'Engine', /^Engineer's Log$/]
for (const node of nodes) {
const treeNode = treeLocator.locator('div').filter({ hasText: isString(node) ? new RegExp(`^${node}$`) : node })
await treeNode.isVisible()
await treeNode.getByRole('button').click()
}
})
})
Reminder, this is only for things with a single quote. The errors work fine as regex:
The error is specific to the one with a quote:
Doing everything one by one works fine: const a = treeLocator.locator('div').filter({ hasText: /^USNS Evers$/ })
await a.isVisible()
await a.getByRole('button').click()
const b = treeLocator.locator('div').filter({ hasText: /^Engine$/ })
await b.isVisible()
await b.getByRole('button').click()
const c = treeLocator.locator('div').filter({ hasText: /^Engineer's Log$/ })
await c.isVisible()
await c.click() |
I still can't repro this, but are you sure doing it one by one works? You seem to be forgetting getByRole in the third iteration. If it works with getByRole as well, it would mean you found a bug in JavaScript! |
Ok, I was able to repro it. Internal repro: console.log(asLocator('javascript', `div >> internal:has-text=/a'b/ >> internal:role=button`)); Results in locator('div').filter({ hasText: '/a\'b/ >> internal:role=button' }) Should be locator('div').filter({ hasText: /a'b/ }).getByRole('button') |
I'm reworking a locator in a POM and it seems like Playwright is mangling a regexp I pass as a filter. I have a tree POM with a method for selecting a specific node by it's text. For convenience I want to turn a basic string into a regex. The regex alone works fine, but when passed to the RegExp constructor, playwright throws an error. It seems like Playwright is somehow altering it.
I originally asked for help in discord and was asked to file an issue here.
System info
Source code
See below
Steps
Expected
No error. My RegExp constructor works fine in vanilla JS so why would it be a problem in Playwright?
Actual
This only errors when there's a single quote in my text string. Everything without a single quote works fine.
The text was updated successfully, but these errors were encountered: