fix: change storage state type to String (#250)

This commit is contained in:
Yury Semikhatsky 2021-02-02 18:05:57 -08:00 committed by GitHub
parent a577e62ece
commit b60bbc8b88
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 75 additions and 141 deletions

View File

@ -218,11 +218,14 @@ public interface Browser extends AutoCloseable {
*/
public RecordVideo recordVideo;
/**
* Populates context with given storage state. This method can be used to initialize context with logged-in information
* obtained via [{@code method: BrowserContext.storageState}]. Either a path to the file with saved storage, or an object with
* the following fields:
* Populates context with given storage state. This option can be used to initialize context with logged-in information
* obtained via [{@code method: BrowserContext.storageState}].
*/
public String storageState;
/**
* Populates context with given storage state. This option can be used to initialize context with logged-in information
* obtained via [{@code method: BrowserContext.storageState}]. Path to the file with saved storage state.
*/
public BrowserContext.StorageState storageState;
public Path storageStatePath;
/**
* Changes the timezone of the context. See
@ -307,13 +310,11 @@ public interface Browser extends AutoCloseable {
this.recordVideo = new RecordVideo();
return this.recordVideo;
}
public NewContextOptions withStorageState(BrowserContext.StorageState storageState) {
public NewContextOptions withStorageState(String storageState) {
this.storageState = storageState;
this.storageStatePath = null;
return this;
}
public NewContextOptions withStorageState(Path storageStatePath) {
this.storageState = null;
public NewContextOptions withStorageStatePath(Path storageStatePath) {
this.storageStatePath = storageStatePath;
return this;
}
@ -507,11 +508,14 @@ public interface Browser extends AutoCloseable {
*/
public RecordVideo recordVideo;
/**
* Populates context with given storage state. This method can be used to initialize context with logged-in information
* obtained via [{@code method: BrowserContext.storageState}]. Either a path to the file with saved storage, or an object with
* the following fields:
* Populates context with given storage state. This option can be used to initialize context with logged-in information
* obtained via [{@code method: BrowserContext.storageState}].
*/
public String storageState;
/**
* Populates context with given storage state. This option can be used to initialize context with logged-in information
* obtained via [{@code method: BrowserContext.storageState}]. Path to the file with saved storage state.
*/
public BrowserContext.StorageState storageState;
public Path storageStatePath;
/**
* Changes the timezone of the context. See
@ -596,13 +600,11 @@ public interface Browser extends AutoCloseable {
this.recordVideo = new RecordVideo();
return this.recordVideo;
}
public NewPageOptions withStorageState(BrowserContext.StorageState storageState) {
public NewPageOptions withStorageState(String storageState) {
this.storageState = storageState;
this.storageStatePath = null;
return this;
}
public NewPageOptions withStorageState(Path storageStatePath) {
this.storageState = null;
public NewPageOptions withStorageStatePath(Path storageStatePath) {
this.storageStatePath = storageStatePath;
return this;
}

View File

@ -54,46 +54,6 @@ public interface BrowserContext extends AutoCloseable {
}
}
class StorageState {
public List<AddCookie> cookies;
public List<OriginState> origins;
public static class OriginState {
public final String origin;
public List<LocalStorageItem> localStorage;
public static class LocalStorageItem {
public String name;
public String value;
public LocalStorageItem(String name, String value) {
this.name = name;
this.value = value;
}
}
public OriginState(String origin) {
this.origin = origin;
}
public OriginState withLocalStorage(List<LocalStorageItem> localStorage) {
this.localStorage = localStorage;
return this;
}
}
public StorageState() {
cookies = new ArrayList<>();
origins = new ArrayList<>();
}
public List<AddCookie> cookies() {
return this.cookies;
}
public List<OriginState> origins() {
return this.origins;
}
}
void onClose(Consumer<BrowserContext> handler);
void offClose(Consumer<BrowserContext> handler);
@ -431,13 +391,13 @@ public interface BrowserContext extends AutoCloseable {
* @param offline Whether to emulate network being offline for the browser context.
*/
void setOffline(boolean offline);
default StorageState storageState() {
default String storageState() {
return storageState(null);
}
/**
* Returns storage state for this browser context, contains current cookies and local storage snapshot.
*/
StorageState storageState(StorageStateOptions options);
String storageState(StorageStateOptions options);
default void unroute(String url) { unroute(url, null); }
default void unroute(Pattern url) { unroute(url, null); }
default void unroute(Predicate<String> url) { unroute(url, null); }

View File

@ -658,8 +658,9 @@ public interface BrowserType {
* context will automatically close the browser.
*
* @param userDataDir Path to a User Data Directory, which stores browser session data like cookies and local storage. More details for
* [Chromium](https://chromium.googlesource.com/chromium/src/+/master/docs/user_data_dir.md) and
* [Firefox](https://developer.mozilla.org/en-US/docs/Mozilla/Command_Line_Options#User_Profile).
* [Chromium](https://chromium.googlesource.com/chromium/src/+/master/docs/user_data_dir.md#introduction) and
* [Firefox](https://developer.mozilla.org/en-US/docs/Mozilla/Command_Line_Options#User_Profile). Note that Chromium's user
* data directory is the **parent** directory of the "Profile Path" seen at {@code chrome://version}.
*/
BrowserContext launchPersistentContext(Path userDataDir, LaunchPersistentContextOptions options);
/**

View File

@ -313,12 +313,12 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
}
@Override
public StorageState storageState(StorageStateOptions options) {
public String storageState(StorageStateOptions options) {
return withLogging("BrowserContext.storageState", () -> {
JsonElement json = sendMessage("storageState");
StorageState storageState = gson().fromJson(json, StorageState.class);
String storageState = json.toString();
if (options != null && options.path != null) {
Utils.writeToFile(json.toString().getBytes(StandardCharsets.UTF_8), options.path);
Utils.writeToFile(storageState.getBytes(StandardCharsets.UTF_8), options.path);
}
return storageState;
});

View File

@ -16,6 +16,7 @@
package com.microsoft.playwright.impl;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.microsoft.playwright.*;
@ -23,6 +24,8 @@ import com.microsoft.playwright.*;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@ -90,14 +93,23 @@ class BrowserImpl extends ChannelOwner implements Browser {
options = new NewContextOptions();
}
if (options.storageStatePath != null) {
try (FileReader reader = new FileReader(options.storageStatePath.toFile())) {
options.storageState = gson().fromJson(reader, BrowserContext.StorageState.class);
try {
byte[] bytes = Files.readAllBytes(options.storageStatePath);
options.storageState = new String(bytes, StandardCharsets.UTF_8);
options.storageStatePath = null;
} catch (IOException e) {
throw new PlaywrightException("Failed to read storage state from file", e);
}
}
JsonObject storageState = null;
if (options.storageState != null) {
storageState = new Gson().fromJson(options.storageState, JsonObject.class);
options.storageState = null;
}
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
if (storageState != null) {
params.add("storageState", storageState);
}
JsonElement result = sendMessage("newContext", params);
BrowserContextImpl context = connection.getExistingObject(result.getAsJsonObject().getAsJsonObject("context").get("guid").getAsString());
if (options.recordVideo != null) {

View File

@ -43,9 +43,10 @@ public class TestBrowserContextStorageState extends TestBase {
page.evaluate("localStorage['name1'] = 'value1';");
page.navigate("https://www.domain.com");
page.evaluate("localStorage['name2'] = 'value2';");
BrowserContext.StorageState storageState = context.storageState();
assertJsonEquals("[{\n" +
String storageState = context.storageState();
assertJsonEquals("{" +
"cookies:[]," +
"origins:[{\n" +
" origin: 'https://www.example.com',\n" +
" localStorage: [{\n" +
" name: 'name1',\n" +
@ -57,15 +58,22 @@ public class TestBrowserContextStorageState extends TestBase {
" name: 'name2',\n" +
" value: 'value2'\n" +
" }]\n" +
"}]", storageState.origins());
"}]}", new Gson().fromJson(storageState, JsonObject.class));
}
@Test
void shouldSetLocalStorage() {
BrowserContext.StorageState storageState = new BrowserContext.StorageState();
storageState.origins.add(new BrowserContext.StorageState.OriginState("https://www.example.com")
.withLocalStorage(Arrays.asList(
new BrowserContext.StorageState.OriginState.LocalStorageItem("name1", "value1"))));
String storageState = "{\n" +
" origins: [\n" +
" {\n" +
" origin: 'https://www.example.com',\n" +
" localStorage: [{\n" +
" name: 'name1',\n" +
" value: 'value1'\n" +
" }]\n" +
" }\n" +
" ]\n" +
"}";
BrowserContext context = browser.newContext(new Browser.NewContextOptions().withStorageState(storageState));
Page page = context.newPage();
page.route("**/*", route -> {
@ -90,7 +98,7 @@ public class TestBrowserContextStorageState extends TestBase {
" return document.cookie;\n" +
"}");
Path path = tempDir.resolve("storage-state.json");
BrowserContext.StorageState state = context.storageState(new BrowserContext.StorageStateOptions().withPath(path));
context.storageState(new BrowserContext.StorageStateOptions().withPath(path));
JsonObject expected = new Gson().fromJson(
"{\n" +
" \"cookies\":[\n" +
@ -117,7 +125,7 @@ public class TestBrowserContextStorageState extends TestBase {
try (InputStreamReader reader = new InputStreamReader(new FileInputStream(path.toFile()), StandardCharsets.UTF_8)) {
assertEquals(expected, new Gson().fromJson(reader, JsonObject.class));
}
BrowserContext context2 = browser.newContext(new Browser.NewContextOptions().withStorageState(path));
BrowserContext context2 = browser.newContext(new Browser.NewContextOptions().withStorageStatePath(path));
Page page2 = context2.newPage();
page2.route("**/*", route -> {
route.fulfill(new Route.FulfillOptions().withBody("<html></html>"));

View File

@ -1 +1 @@
1.9.0-next-1612297085000
1.9.0-next-1612316912000

View File

@ -21,11 +21,9 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import javax.crypto.spec.PSource;
import java.io.*;
import java.nio.file.FileSystems;
import java.util.*;
import java.util.stream.Collectors;
import static java.util.Arrays.asList;
import static java.util.Collections.reverse;
@ -826,12 +824,6 @@ class Field extends Element {
output.add(offset + access + "Optional<" + type.toJava() + "> " + name + ";");
return;
}
if (asList("Browser.newContext.options.storageState",
"Browser.newPage.options.storageState").contains(jsonPath)) {
output.add(offset + access + type.toJava() + " " + name + ";");
output.add(offset + access + "Path " + name + "Path;");
return;
}
output.add(offset + access + type.toJava() + " " + name + ";");
}
@ -896,20 +888,6 @@ class Field extends Element {
output.add(offset + "}");
return;
}
if (asList("Browser.newContext.options.storageState",
"Browser.newPage.options.storageState").contains(jsonPath)) {
output.add(offset + "public " + parentClass + " withStorageState(BrowserContext.StorageState storageState) {");
output.add(offset + " this.storageState = storageState;");
output.add(offset + " this.storageStatePath = null;");
output.add(offset + " return this;");
output.add(offset + "}");
output.add(offset + "public " + parentClass + " withStorageState(Path storageStatePath) {");
output.add(offset + " this.storageState = null;");
output.add(offset + " this.storageStatePath = storageStatePath;");
output.add(offset + " return this;");
output.add(offset + "}");
return;
}
if ("Route.continue_.options.postData".equals(jsonPath)) {
output.add(offset + "public " + parentClass + " withPostData(String postData) {");
output.add(offset + " this.postData = postData.getBytes(StandardCharsets.UTF_8);");
@ -1153,46 +1131,6 @@ class Interface extends TypeDefinition {
output.add(offset + " }");
output.add(offset + "}");
output.add("");
output.add(offset + "class StorageState {");
output.add(offset + " public List<AddCookie> cookies;");
output.add(offset + " public List<OriginState> origins;");
output.add("");
output.add(offset + " public static class OriginState {");
output.add(offset + " public final String origin;");
output.add(offset + " public List<LocalStorageItem> localStorage;");
output.add("");
output.add(offset + " public static class LocalStorageItem {");
output.add(offset + " public String name;");
output.add(offset + " public String value;");
output.add(offset + " public LocalStorageItem(String name, String value) {");
output.add(offset + " this.name = name;");
output.add(offset + " this.value = value;");
output.add(offset + " }");
output.add(offset + " }");
output.add("");
output.add(offset + " public OriginState(String origin) {");
output.add(offset + " this.origin = origin;");
output.add(offset + " }");
output.add("");
output.add(offset + " public OriginState withLocalStorage(List<LocalStorageItem> localStorage) {");
output.add(offset + " this.localStorage = localStorage;");
output.add(offset + " return this;");
output.add(offset + " }");
output.add(offset + " }");
output.add("");
output.add(offset + " public StorageState() {");
output.add(offset + " cookies = new ArrayList<>();");
output.add(offset + " origins = new ArrayList<>();");
output.add(offset + " }");
output.add("");
output.add(offset + " public List<AddCookie> cookies() {");
output.add(offset + " return this.cookies;");
output.add(offset + " }");
output.add(offset + " public List<OriginState> origins() {");
output.add(offset + " return this.origins;");
output.add(offset + " }");
output.add(offset + "}");
output.add("");
break;
}
case "Browser": {
@ -1440,6 +1378,7 @@ public class ApiGenerator {
// Rename in place.
object.addProperty("name", alias);
}
overrideType(object);
for (Map.Entry<String, JsonElement> entry : object.entrySet()) {
if (isSupported(entry.getValue())) {
filterOtherLangs(entry.getValue());
@ -1453,6 +1392,21 @@ public class ApiGenerator {
}
}
private static void overrideType(JsonObject jsonObject) {
if (!jsonObject.has("langs")) {
return;
}
JsonObject langs = jsonObject.getAsJsonObject("langs");
if (!langs.has("types")) {
return;
}
JsonElement type = langs.getAsJsonObject("types").get("java");
if (type == null) {
return;
}
jsonObject.add("type", type);
}
private static String alias(JsonObject jsonObject) {
if (!jsonObject.has("langs")) {
return null;

View File

@ -173,7 +173,6 @@ class Types {
add("BrowserContext.addCookies.cookies.sameSite", "\"Lax\"|\"None\"|\"Strict\"", "SameSite", new Empty());
add("BrowserContext.route.url", "RegExp|function(URL):boolean|string", "String");
add("BrowserContext.unroute.url", "RegExp|function(URL):boolean|string", "String");
add("BrowserContext.storageState", "Object", "StorageState", new Empty());
add("Page.waitForNavigation.options.url", "RegExp|function(URL):boolean|string", "Custom");
add("Page.waitForNavigation.options", "Object", "WaitForNavigationOptions");
add("Page.waitForRequest.options", "Object", "WaitForRequestOptions");
@ -198,8 +197,6 @@ class Types {
add("BrowserContext.setGeolocation.geolocation", "Object|null", "Geolocation", new Empty());
add("Browser.newContext.options.geolocation", "Object", "Geolocation", new Empty());
add("Browser.newContext.options.storageState", "Object|path", "BrowserContext.StorageState", new Empty());
add("Browser.newPage.options.storageState", "Object|path", "BrowserContext.StorageState", new Empty());
add("Browser.newPage.options.geolocation", "Object", "Geolocation", new Empty());
add("BrowserType.launchPersistentContext.options.geolocation", "Object", "Geolocation", new Empty());