Playwright元素交互异常:frameLocator识别object而非iframe报错
解决Playwright中
<object>标签而非<iframe>导致的定位失败问题 问题根源
错误提示明确说明:你使用frameLocator定位的#obj_eXXXXX_wab_application是<object type="text/html">元素,但frameLocator仅支持<iframe>标签,这就是代码超时、报错的核心原因。
解决方案:直接操作<object>内部文档
Playwright无法通过frameLocator处理<object>,但可以通过获取<object>的contentDocument来访问其内部内容,具体实现如下:
方法一:转换为新Page对象操作
test('test', async ({ page }) => { await page.goto('about:blank'); await page.goto('https://xxxx.xxx.xxx/portal/'); await page.getByPlaceholder('User ID').fill('username'); await page.getByLabel('Password', { exact: true }).fill('password'); await page.getByLabel('Password', { exact: true }).click(); await page.getByLabel('Welcome to Login Section. All').getByText('I agree to the Terms and').click(); await page.getByRole('button', { name: 'Login' }).click(); await page.getByText('xxxx TEST').click(); await page.getByRole('link', { name: 'Application' }).click(); // 等待object内容加载完成 await page.waitForFunction( selector => document.querySelector(selector)?.contentDocument?.readyState === 'complete', '#obj_xxxx_wab_application' ); // 获取object元素及内部文档 const objectElement = await page.locator('#obj_xxxx_wab_application').elementHandle(); const objectDoc = await objectElement?.evaluateHandle(el => el.contentDocument); const objectPage = await page.context().newPage(); await objectPage.setContent(await objectDoc?.evaluate(doc => doc.documentElement.outerHTML) || ''); // 操作object内部元素 await objectPage.getByLabel('Logged In As:').selectOption('data_entry'); await objectPage.getByLabel('Logged In As:').selectOption('data_extractor'); await objectPage.getByRole('button', { name: 'Submit' }).click(); });
方法二:直接在浏览器上下文内操作(无需新建Page)
test('test', async ({ page }) => { await page.goto('about:blank'); await page.goto('https://xxxx.xxx.xxx/portal/'); await page.getByPlaceholder('User ID').fill('username'); await page.getByLabel('Password', { exact: true }).fill('password'); await page.getByLabel('Password', { exact: true }).click(); await page.getByLabel('Welcome to Login Section. All').getByText('I agree to the Terms and').click(); await page.getByRole('button', { name: 'Login' }).click(); await page.getByText('xxxx TEST').click(); await page.getByRole('link', { name: 'Application' }).click(); // 等待object内容加载完成 await page.waitForFunction( selector => document.querySelector(selector)?.contentDocument?.readyState === 'complete', '#obj_xxxx_wab_application' ); // 直接在浏览器上下文中操作object内部元素 await page.evaluate(() => { const obj = document.getElementById('obj_xxxx_wab_application'); const doc = obj?.contentDocument; if (!doc) return; // 选择下拉选项 const selectEl = doc.querySelector('[label="Logged In As:"]') as HTMLSelectElement; selectEl.value = 'data_extractor'; selectEl.dispatchEvent(new Event('change')); // 触发必要的事件 // 点击提交按钮 doc.querySelector('[role="button"][name="Submit"]')?.click(); }); });
内容的提问来源于stack exchange,提问作者Bristi
相关产品推荐
相关产品推荐

