(1). 概述

当使用Playwright进行自动化测试时,遇到网页需要人工交付这种功能(比如:登录需要验证码或者方块滑动验证),一般的实现方式有几种:

(2). 功能介绍

以京东为例:

(3). Cookie和Session存储

package org.example;

import com.microsoft.playwright.*;
import org.apache.commons.io.FileUtils;

import java.io.*;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.TimeUnit;

public class StoreCookieAndSessionTest {
  public static void main(String[] args) throws Exception {
    try (Playwright playwright = Playwright.create()) {
      Browser browser = playwright.chromium().launch(new BrowserType.LaunchOptions().setHeadless(false));
      BrowserContext browserContext = browser.newContext();
      Page page = browserContext.newPage();
      // 1. 导航到京东
      page.navigate("https://www.jd.com/");

      // 2. 休息80秒(等待用户输入账号/密码/验证码...登录)
      TimeUnit.SECONDS.sleep(80);
      // 3. 登录之后,存储Cookie到本地磁盘
      browserContext.storageState(new BrowserContext.StorageStateOptions().setPath(Paths.get("/Users/lixin/GitRepository/playwright-java/examples/jd-cookie.json")));

      // 4. 通过JS语法,把所有的session转换成为JSON
      String sessionStorage = (String) page.evaluate("JSON.stringify(sessionStorage)");
      // 5. 存储Session信息到本地磁盘
      Path session = Paths.get("/Users/lixin/GitRepository/playwright-java/examples/jd-session.txt");
      FileUtils.writeStringToFile(session.toFile(), sessionStorage);
      // 6. 在这种情况下,手上执有了:Cookie和Session了.
    }
  }
}

(4). 读取Session和Cookie

package org.example;

import com.microsoft.playwright.*;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.StringReader;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.TimeUnit;

public class JDAutoLoginTest {
  public static void main(String[] args) throws Exception {
    try (Playwright playwright = Playwright.create()) {
      // 1. 读取磁盘上的Session
      Path sessionPath = Paths.get("/Users/lixin/GitRepository/playwright-java/examples/jd-session.txt");
      String sessionStorage = FileUtils.readFileToString(sessionPath.toFile(), "UTF-8");

      Browser browser = playwright.chromium().launch(new BrowserType.LaunchOptions().setHeadless(false));
      // 2. 指定Cookie存储位置
      BrowserContext browserContext = browser.newContext(new Browser.NewContextOptions().setStorageStatePath(Paths.get("/Users/lixin/GitRepository/playwright-java/examples/jd-cookie.json")));
      // 3. 通过JS设置session信息
      browserContext.addInitScript("(storage => {\n" +
        "  if (window.location.hostname === 'jd.com') {\n" +
        "    const entries = JSON.parse(storage);\n" +
        "     for (const [key, value] of Object.entries(entries)) {\n" +
        "      window.sessionStorage.setItem(key, value);\n" +
        "    };\n" +
        "  }\n" +
        "})('" + sessionStorage + "')");

      Page page = browserContext.newPage();
      page.navigate("https://www.jd.com/");
      TimeUnit.HOURS.sleep(1);
    }
  }
}

(5). 结果验证

"京东自动登录功能"

(6). 总结

通过这个案例,可以证实一点,第一次需要用户介入登录,然后,复制会话信息,赋值到新的浏览器之后,登录的状态依然是有效的.