javascript 从Playwright收到错误“Execution context was destroyed,most likely because a navigation”

x759pob2  于 2023-06-20  发布在  Java
关注(0)|答案(1)|浏览(606)

我已经建立了一个小的帮助函数,试图帮助使嵌套循环更容易读/写在我的剧作家脚本,但我现在遇到这个错误。
因为我使用async/await,所以在我有机会执行代码之前,我不确定导航为什么或在哪里继续。
我可以手动写出实用函数,它似乎可以工作,但将其创建为函数会产生此错误。
除了错误本身,我不介意任何关于改进/学习代码和方法的指针或建议。

效用函数

loopOverLocators: async (locator, callback) => {
        for (let i = 0; i < await locator.count(); i++) 
        {
            callback(locator.nth(i))
        }
    }

主文件

import { test, expect } from "@playwright/test";
import fs from 'fs'
import path from 'path'
import dotenv from 'dotenv'
dotenv.config({ override: true })
import { createOutputFile, getInputFromHeader, loopOverLocators } from '../helpers/utils'
import paths from '../get-paths'

const USERNAME = process.env.USERNAME
const PASSWORD = process.env.PASSWORD

const filename = "all-test-entities.csv"
const headers = JSON.parse(fs.readFileSync(path.join(paths.helpers_dir, 'get-headers.json'), 'utf-8'))
const countries = JSON.parse(fs.readFileSync(path.join(paths.helpers_dir, 'get-countries.json'), 'utf-8'))
const file = createOutputFile(filename)

test("Output all test entities to CSV file", async ({ page }) => {

    let test_entities = []

    await page.goto('https://adminportal.trulioo.com/Account/LogOn');
    await page.locator('#UserName').click();
    await page.locator('#UserName').fill(USERNAME);
    await page.locator('#Password').click();
    await page.locator('#Password').fill(PASSWORD);
    await page.getByRole('button', { name: 'Sign In' }).click();
    await page.frameLocator('#duo_iframe').getByRole('button', { name: 'Send Me a Push' }).click();

    await page.getByRole('link', { name: 'Admin Portal' }).click();
    await page.getByRole('link', { name: 'Global', exact: true }).click();
    await page.getByRole('link', { name: 'Manage Default Test Entities' }).click();

    for (const country_option of countries.options)
    {
        console.log("Entered " + country_option)
        await page.locator('#SelectedConfiguration').selectOption(country_option);
        await page.getByRole('button', { name: 'View Test Entities' }).click();
        await page.waitForSelector('.default-test-entity')

        // loop over `.default-test-entity locators`
        const test_entity_locators = page.locator('.default-test-entity')
        loopOverLocators(test_entity_locators, async (test_entity) => {
            console.log(await test_entity)
        })
    }
})

错误

Error: locator.count: Execution context was destroyed, most likely because of a navigation

       at ..\helpers\utils.js:38

      36 |     },
      37 |     loopOverLocators: async (locator, callback) => {
    > 38 |         for (let i = 0; i < await locator.count(); i++)
         |                                           ^
      39 |         {
      40 |             callback(locator.nth(i))
      41 |         }

        at loopOverLocators (C:\Development\create-test-entities\helpers\utils.js:38:43)

我尝试在实用程序函数和主脚本中添加额外的async/waiting,看看是否可以让脚本在继续导航之前等待代码运行。
我可以删除这个实用函数,并手动写出每次迭代的for循环,但我想弄清楚为什么这不起作用。

ux6nzvsh

ux6nzvsh1#

你可以使用all()方法等待所有的定位器,并最终将数组传递给helper函数(在我看来,这对可读性没有帮助):

test('Test', async ({ page }) => {
    // Ref. documentation, make sure that the page is loaded before 
    // doing all(), by e.g. using waitForLoadState
    await page.waitForLoadState('networkidle')
    const test_entity_locators = await page.locator('.default-test-entity').all()
    
    // Do it directly
    for (const entity of test_entity_locators) {
        console.log(entity)
    }

    // ...or by using a helper function
    await loopOverLocators(test_entity_locators)
})

const loopOverLocators = async (locatorArray: Locator[]) => {
    for (const entity of locatorArray) {
        console.log(entity)
    }
}

相关问题