Học Playwright tiếng Việt, Cộng đồng Playwright cho người Việt

Vọc Vạch Playwright

[Vọc Playwright] – Network

https://playwright.dev/docs/network

Introduction

  • Playwright cung cấp các API để monitormodify lưu lượng mạng của trình duyệt, bao gồm cả HTTP và HTTPS. Mọi request mà 1 trang web thực hiện, bao gồm cả XHRs và các yêu cầu fetch, đều có thể được theo dõi, sửa đổi và xử lý

Mock APIs

  • Mock các APIs request, để trang web không cần phải kết nối với máy chủ thật
  • Thực hiện các yêu cầu API và sửa đổi response trước khi nó được gửi đến trang web
  • Sử dụng file HAR để mô phỏng network request

Network Mocking

  • Bạn không cần phải cấu hình phức tạp để mô phỏng network request. Chỉ cần định nghĩa 1 Route tuỳ chỉnh để mô phỏng network cho một brower context
import { test, expect } from '@playwright/test';

test.beforeEach(async ({ context }) => {
  // Block any css requests for each test in this file.
  await context.route(/.css$/, route => route.abort());
});

test('loads page without css', async ({ page }) => {
  await page.goto('https://playwright.dev');
  // ... test goes here
});
  • Ngoài ra bạn cũng có thể sử dụng page.route() để mock cho 1 trang web cụ thể
import { test, expect } from '@playwright/test';

test('loads page without images', async ({ page }) => {
  // Block png and jpeg images.
  await page.route(/(png|jpeg)$/, route => route.abort());

  await page.goto('https://playwright.dev');
  // ... test goes here
});

HTTP Authentication

  • Thực hiện xác thực HTTP
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
  use: {
    httpCredentials: {
      username: 'bill',
      password: 'pa55w0rd',
    }
  }
});

Proxy HTTP

  • Bạn có thể cấu hình các trang web để tải thông qua proxy HTTP(S) hoặc SOCKSv5.
  • Playwright cho phép bạn cấu hình proxy cho toàn bộ trình duyệt hoặc cho mỗi context riêng biệt
  • Bạn có thể đặt username và password cho proxy, cũng như chỉ định các host mà proxy sẽ bỏ qua
  • Đây là ví dụ về proxy global
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
  use: {
    proxy: {
      server: 'http://myproxy.com:3128',
      username: 'usr',
      password: 'pwd'
    }
  }
});
  • Khi chỉ định proxy cho mỗi ngữ cảnh riêng lẻ, Chromium trên Windows cần một chỉ dẫn rằng proxy sẽ được thiết lập. Điều này được thực hiện bằng cách truyền một proxy server không rỗng cho chính trình duyệt. Dưới đây là một ví dụ về proxy cụ thể cho từng ngữ cảnh
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
  use: {
    launchOptions: {
      // Browser proxy option is required for Chromium on Windows.
      proxy: { server: 'per-context' }
    },
    proxy: {
      server: 'http://myproxy.com:3128',
    }
  }
});

Network Events

  • Bạn có thể theo dõi tất cả requestsresponses của trang web
// Subscribe to 'request' and 'response' events.
page.on('request', request => console.log('>>', request.method(), request.url()));
page.on('response', response => console.log('<<', response.status(), response.url()));

await page.goto('https://example.com');
  • Hoặc đợi network response sau khi nhấn nút bằng page.waitForResponse()
// Use a glob URL pattern. Note no await.
const responsePromise = page.waitForResponse('**/api/fetch_data');
await page.getByText('Update').click();
const response = await responsePromise;

Variations

  • Chờ đợi response với page.waitForResponse()
// Use a RegExp. Note no await.
const responsePromise = page.waitForResponse(/\.jpeg$/);
await page.getByText('Update').click();
const response = await responsePromise;

// Use a predicate taking a Response object. Note no await.
const responsePromise = page.waitForResponse(response => response.url().includes(token));
await page.getByText('Update').click();
const response = await responsePromise;

Handle requests

await page.route('**/api/fetch_data', route => route.fulfill({
  status: 200,
  body: testData,
}));
await page.goto('https://example.com');
  • Bạn có thể mô phỏng các API endpoints thông qua việc xử lý network requests

Variantions

  • Thiết lập route cho toàn bộ browser context browserContext.route() hoặc trang với page.route(). Nó sẽ áp dụng cho popup và các link được mở
await browserContext.route('**/api/login', route => route.fulfill({
  status: 200,
  body: 'accept',
}));
await page.goto('https://example.com');

Modify requests

// Delete header
await page.route('**/*', async route => {
  const headers = route.request().headers();
  delete headers['X-Secret'];
  await route.continue({ headers });
});

// Continue requests as POST.
await page.route('**/*', route => route.continue({ method: 'POST' }));
  • Bạn có thể tiếp tục các request với những chỉnh sửa. Ví dụ xoá 1 header HTTP khỏi các yêu cầu đang được gửi đi

Abort requests

  • Bạn có thể huỷ bỏ yêu cầu bằng cách sử dụng page.route()route.abort()
await page.route('**/*.{png,jpg,jpeg}', route => route.abort());

// Abort based on the request type
await page.route('**/*', route => {
  return route.request().resourceType() === 'image' ? route.abort() : route.continue();
});

Modify responses

  • Để chỉnh sửa 1 response, hãy sử dụng APIRequestContext để lấy response gốc và sau đó chuyển response này đến route.fulfill(). Bạn có thể ghi đè các trường cụ thể trong response thông qua các option
await page.route('**/title.html', async route => {
  // Fetch original response.
  const response = await route.fetch();
  // Add a prefix to the title.
  let body = await response.text();
  body = body.replace('<title>', '<title>My prefix:');
  await route.fulfill({
    // Pass all fields from the response.
    response,
    // Override response body.
    body,
    // Force content type to be html.
    headers: {
      ...response.headers(),
      'content-type': 'text/html'
    }
  });
});

WebSockets

  • Playwright hỗ trợ kiểm tra WebSockets ngay từ đầu. Mỗi khi 1 WebSocket được tạo, event `page.on(‘websocket’) sẽ được kích hoạt. Event này chứa object WebSocket để kiểm tra các khung WebSocket
page.on('websocket', ws => {
  console.log(`WebSocket opened: ${ws.url()}>`);
  ws.on('framesent', event => console.log(event.payload));
  ws.on('framereceived', event => console.log(event.payload));
  ws.on('close', () => console.log('WebSocket closed'));
});

Missing Network Events and Service Workers

  • Các function browserContext.route() và page.route() cho phép kiểm tra gốc rễ của các request và thực hiện mocking và interception
  • Nếu bạn sử dụng các hàm browserContext.route()page.route() của Playwright và nhận thấy thiếu các network events, hãy tắt Service Workers bằng cách đặt Browser.newContext.serviceWorkers thành ‘block’.
  • Có thể bạn đang sử dụng công cụ giả lập như Mock Service Worker (MSW). Dù công cụ này hoạt động tốt để giả lập request, nhưng nó thêm 1 Service Worker của riêng mình để quản lý các network events, làm cho chúng không thể thây được bởi browserContext.route()page.route(). Nếu bạn muốn cả network testing and mocking, hãy cân nhắc sử dụng browserContext.route() và page.route() tích hợp sẵn để giả lập phản hồi.
  • Nếu bạn quan tâm đến việc không chỉ sử dụng Service Workers để testing và network mocking, mà còn điề hướng và lắng nghe các yêu cầu do Service Workers thực hiện, vui lòng tham khảo https://github.com/microsoft/playwright/issues/15684

Trả lời