我正在try 使用编剧打字脚本创建一个基本的注册脚本.如果我使用调试模式并单步执行代码,它运行得很好,但如果我使用Headless,它就失败了.try 填写邮箱字段时失败.我正在使用的定位器能够找到元素,但它会try 等待它可见,即使它出现在页面上.Html上没有iframe.

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



class RegisterStr{
  userName: Locator;
  pw: Locator;
  button: Locator;
  

  constructor(page: Page){
    this.userName = page.locator('#username')
    this.pw = page.getByLabel('#password')
    this.button = page.locator("#submit")
  }
}


test.describe("Resgietring", ()=>{
  let regis : RegisterStr;

  test('has title', async ({ page }) => {
    regis = new RegisterStr(page)
    await page.goto('https://practicetestautomation.com/practice-test-login/');

    regis.userName.fill("student")
    regis.pw.fill("Password123")
    regis.button.click();
  
    // await page.waitForURL("https://practicetestautomation.com/logged-in-successfully/")
  
    // Expect signed in 
    await expect(page.getByRole('heading', { name: 'Logged In Successfully' })).toBeVisible();
  });
})

Error Shown

推荐答案

我认为有两个问题:

  1. 你需要将所有返回promise的Playwright API调用设为await.如果不这样做会导致竞争条件和不确定性,这意味着脚本可能会随机失败,并产生令人困惑的错误或不可预测的行为.
  2. 将css Select 器传递到定位器时,请使用.locator()而不是.getByLabel().

对我来说,应用这些修复程序可以通过测试(我使用的是JS,而不是TS,但这无关紧要):

import {expect, test} from "@playwright/test"; // ^1.39.0

class Register {
  constructor(page) {
    this.userName = page.locator("#username");
    this.pw = page.locator("#password");
    this.button = page.locator("#submit");
  }
}

test.describe("Registering", () => {
  test("has title", async ({page}) => {
    const regis = new Register(page);
    await page.goto(
      "https://practicetestautomation.com/practice-test-login/"
    );
    await regis.userName.fill("student");
    await regis.pw.fill("Password123");
    await regis.button.click();
    await page.waitForURL(
      "https://practicetestautomation.com/logged-in-successfully/"
    );
    await expect(
      page.getByRole("heading", {name: "Logged In Successfully"})
    ).toBeVisible();
  });
});

除了正确之外,这里的POM人可能应该比现在做更多的工作.在POM中有一些定位器和没有一些定位器是不一致的,通常情况下,添加抽象出一些"原始"编剧操作的方法是有用的.

Typescript相关问答推荐

如何修复VueJS中的val类型不能赋给函数

Angular 17 -如何使用新的@if语法在对象中使用Deliverc值

react 路由6操作未订阅从react 挂钩表单提交+也不使用RTK查询Mutations

如何使用泛型自动推断TS中的类型

在包含泛型的类型脚本中引用递归类型A<;-&B

在函数中打字推断记录的关键字

表单嵌套太深

Vue3 Uncaught SyntaxError:每当我重新加载页面时,浏览器控制台中会出现无效或意外的令牌

在VSCode中显示eslint错误,但在终端中运行eslint命令时不显示?(Vite,React,TypeScript)

类型实例化过深,可能是无限的&TypeScrip中的TupleUnion错误

是否将Angular *ngFor和*ngIf迁移到新的v17语法?

为什么在这种情况下,打字脚本泛型无法正确自动完成?

如何在Angular /字体中访问API响应的子元素?

使用强制转换编写打字函数的惯用方法

我如何键入它,以便具有字符串或数字构造函数的数组可以作为字符串或数字键入s或n

元素隐式具有any类型,因为string类型的表达式不能用于索引类型{Categories: Element;管理员:元素; }'

React HashRouter,单击导航栏时页面重新加载出现问题

将 Angular 从 14 升级到 16 后出现环境变量注入问题

如何从 Select 元素中删除选项

req.files = 未定义(Multer、Express、Typescript)