Playwright实战-深入理解Browser、Context、Page

 深入理解Browser、Context、Page,可以让我们轻松掌握Playwright的工作原理,并从容应对问题如:如何处理对话框?如何复用登录身份信息?录制调整视频大小或者存储目录?

概念

 在Playwright中,BrowserContext, 和 Page 是核心概念,它们共同定义了自动化测试的结构。

测试会在浏览器(Browser)的上下文(BrowserContext)中执行,每个上下文包含多个页面(Page)。每个页面都代表了一个打开的浏览器标签页。这种层级结构允许你在同一个浏览器实例中同时执行多个测试用例,以提高效率。

Browser

• Browser 对应于一个完整的浏览器实例,比如 ChromeFirefox 或 WebKit

• Playwright 脚本通常从启动一个 Browser 实例开始,并在测试结束时关闭它。

• Browser 可以在无头(headless)或有头(headful)模式下启动。

const { chromium } = require('playwright');

// 无头模式启动浏览器
async function launchInHeadlessMode() {
  const browser = await chromium.launch({ headless: true });
  console.log('浏览器已在无头模式下启动');
  // 执行其他操作...
  await browser.close();
}

// 有头模式启动浏览器
async function launchInHeadfulMode() {
  const browser = await chromium.launch({ headless: false });
  console.log('浏览器已在有头模式下启动');
  // 执行其他操作...
  await browser.close();
}

// 分别调用无头模式和有头模式启动浏览器的函数
launchInHeadlessMode();
launchInHeadfulMode();

• 一个 Browser 实例可以包含多个BrowserContext。 BrowserContext 代表了浏览器的一个隔离环境,其中包含了一组浏览器窗口(Page)、cookies、缓存、本地存储等。使用多个 BrowserContext 可以帮助模拟不同用户的会话,或者隔离测试环境以避免相互干扰。

BrowserContext

• BrowserContext 代表了一个浏览器的会话,它类似于一个全新的浏览器配置文件。

• Playwright 为每个测试用例创建一个 BrowserContext,以确保测试之间的隔离。

• 每个 BrowserContext 拥有自己的 Cookie、浏览器存储和浏览历史记录。

• 可以在同一个 Browser 实例中创建多个 BrowserContext 来模拟多用户会话。

const { chromium } = require('playwright');

async function main() {
  // 启动一个浏览器实例
  const browser = await chromium.launch();

  // 创建第一个 BrowserContext
  let context1 = await browser.newContext();
  let page1 = await context1.newPage();
  await page1.goto('https://example.com');
  console.log('在第一个上下文中打开网页');

  // 创建第二个 BrowserContext
  let context2 = await browser.newContext();
  let page2 = await context2.newPage();
  await page2.goto('https://example.com');
  console.log('在第二个上下文中打开网页');

  // ... 在这里可以继续创建更多的 BrowserContext 和 Page,并进行相应的操作

  // 关闭所有打开的 BrowserContext
  await context1.close();
  await context2.close();

  // 关闭浏览器实例
  await browser.close();
}

说明如下:

• 启动了一个 Browser 实例,然后创建了两个 BrowserContext 实例。

• 每个 BrowserContext 实例都打开了相同的网页,但由于它们是隔离的,因此它们各自的状态(例如 cookieslocalStorage)不会相互影响。

• 关闭了这两个 BrowserContext 以及最初的 Browser 实例

Page

• Page 是在 BrowserContext 中打开的单个网页。

• 每个 Page 代表了用户与浏览器交互时看到的视图。

• Page 提供了丰富的 API 用于导航、操作元素、处理表单、弹出窗口等。

• 在同一个 BrowserContext 中可以打开多个 Page 实例。

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch();
  const context = await browser.newContext();

  // 打开第一个页面
  const page1 = await context.newPage();
  await page1.goto('https://example.com');
  console.log(await page1.title());

  // 打开第二个页面
  const page2 = await context.newPage();
  await page2.goto('https://example.org');
  console.log(await page2.title());

  // 关闭浏览器
  await browser.close();
})();

说明如下:

• 使用browser.newContext() 创建了一个新的浏览器上下文。

• 通过 context.newPage() 分别创建了两个新的页面实例,即 page1 和 page2,每个页面可以独立进行导航和操作

图片[1]-Playwright实战-深入理解Browser、Context、Page-365博客
Browser
  |--- BrowserContext
        |--- Page
        |--- Page
        |--- ...

典型场景

复用登录身份信息

• 使用同一 BrowserContext 打开多个 Page 可以共享相同的 Cookie,从而复用登录状态。

• 使用 context 的 storageState 方法来实现

• 保存当前上下文的状态,包括登录信息,并在创建新页面时进行恢复

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch();
  const context = await browser.newContext();

  // 在第一个页面登录
  const page1 = await context.newPage();
  await page1.goto('https://example.com/login');
  await page1.fill('input[name=username]', 'your_username');
  await page1.fill('input[name=password]', 'your_password');
  await page1.click('button[type=submit]');

  // 保存上下文状态
  const storageState = await context.storageState();

  // 在新页面中恢复登录状态
  const page2 = await context.newPage();
  await page2.goto('https://example.com/dashboard', { waitUntil: 'domcontentloaded' });

  // 具体的测试逻辑

  await context.close();
  await browser.close();
})();

操作对话框

当 Page 触发弹出对话框时,可以使用 Page 的相关 API 来定位和操作对话框元素。

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch();
  const context = await browser.newContext();
  const page = await context.newPage();

  // 监听 'dialog' 事件
  page.on('dialog', async (dialog) => {
    console.log('Dialog message:', dialog.message());

    // 模拟输入值并点击确定按钮
    await dialog.type('Your input');
    await dialog.accept();
  });

  // 触发一个包含 Prompt 对话框的操作,例如点击一个按钮
  await page.goto('https://example.com');
  await page.click('button');

  // 关闭浏览器
  await browser.close();
})();

说明如下:

• 使用page.on()监听对话框事件

• 通过 dialog.type('Your input') 模拟输入文本,并使用 dialog.accept() 确认对话框

视频录制

通过 Browser 的 browserContext.newPage() 打开 Page 后,可以使用 Browser 的录制功能来保存整个浏览器会话的视频。

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch();
  const context = await browser.newContext({
    viewport: { width: 1920, height: 1080 }, // 设置视口大小为 1920x1080
    recordVideo: { dir: './videos/' } // 设置视频存储路径为当前目录下的 videos 文件夹
  });
  const page = await context.newPage();

  // 打开页面并进行一些操作
  await page.goto('https://example.com');
  // 进行其他操作...

  // 关闭浏览器
  await browser.close();
})();

说明如下:

• chromium.launch() 启动了 Chromium 浏览器实例

• 使用 browser.newContext() 创建了一个新的浏览器上下文,并设置了视口大小为 1920x1080,同时开启了视频录制并设置了存储路径为当前目录下的 videos 文件夹。

• 使用 context.newPage() 创建了一个新的页面。

• 可以在页面上执行各种操作,最后关闭了浏览器。

小结

  深入理解这些概念和它们的关系是理解和有效使用 Playwright 进行自动化测试的基础。通过合理地管理 BrowserContext,和 Page,可以编写出高效、可维护且稳定的自动化测试脚本。

© 版权声明
THE END
喜欢就支持一下吧
点赞11 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容