feat(api): support storage state (#89)

This commit is contained in:
Yury Semikhatsky 2020-12-06 09:27:15 -08:00 committed by GitHub
parent f360de0a09
commit 2c7caa6292
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 171 additions and 62 deletions

View File

@ -116,6 +116,9 @@ class TypeRef extends Element {
if (jsonName.equals("Array<Object>") && "BrowserContext.addCookies.cookies".equals(jsonPath)) {
isClass = true;
}
if (jsonName.equals("Promise<Object>") && "BrowserContext.storageState".equals(jsonPath)) {
isClass = true;
}
Types.Mapping mapping = TypeDefinition.types.findForPath(parentPath);
if (mapping == null) {
if (isEnum) {
@ -423,6 +426,7 @@ class Method extends Element {
}
private static Set<String> skipJavadoc = new HashSet<>(asList(
"BrowserContext.waitForEvent.optionsOrPredicate",
"Page.waitForEvent.optionsOrPredicate",
"Page.frame.options",
"WebSocket.waitForEvent.optionsOrPredicate"
@ -871,6 +875,46 @@ 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": {

View File

@ -253,6 +253,7 @@ class Types {
add("BrowserContext.addCookies.cookies.expires", "number", "Long", new Empty());
add("BrowserContext.route.url", "string|RegExp|function(URL):boolean", "String");
add("BrowserContext.unroute.url", "string|RegExp|function(URL):boolean", "String");
add("BrowserContext.storageState", "Promise<Object>", "StorageState", new Empty());
add("BrowserContext.waitForEvent.event", "string", "EventType", new Empty());
add("BrowserContext.waitForEvent.optionsOrPredicate", "Function|Object", "String");
add("BrowserContext.waitForEvent", "Promise<Object>", "Deferred<Event<EventType>>", new Empty());
@ -297,6 +298,8 @@ class Types {
add("BrowserContext.setGeolocation.geolocation", "null|Object", "Geolocation", new Empty());
add("Browser.newContext.options.geolocation", "Object", "Geolocation", new Empty());
add("Browser.newContext.options.storageState", "Object", "BrowserContext.StorageState", new Empty());
add("Browser.newPage.options.storageState", "Object", "BrowserContext.StorageState", new Empty());
add("Browser.newPage.options.geolocation", "Object", "Geolocation", new Empty());
add("BrowserType.launchPersistentContext.options.geolocation", "Object", "Geolocation", new Empty());
add("Download.saveAs.path", "string", "Path", new Empty());

View File

@ -140,31 +140,6 @@ public interface Browser {
return this;
}
}
public class StorageState {
/**
* Optional cookies to set for context
*/
public List<Object> cookies;
/**
* Optional localStorage to set for context
*/
public List<Object> origins;
StorageState() {
}
public NewContextOptions done() {
return NewContextOptions.this;
}
public StorageState withCookies(List<Object> cookies) {
this.cookies = cookies;
return this;
}
public StorageState withOrigins(List<Object> origins) {
this.origins = origins;
return this;
}
}
/**
* Whether to automatically download all the attachments. Defaults to {@code false} where all the downloads are canceled.
*/
@ -249,7 +224,7 @@ public interface Browser {
/**
* Populates context with given storage state. This method can be used to initialize context with logged-in information obtained via browserContext.storageState().
*/
public StorageState storageState;
public BrowserContext.StorageState storageState;
public NewContextOptions withAcceptDownloads(Boolean acceptDownloads) {
this.acceptDownloads = acceptDownloads;
@ -335,9 +310,9 @@ public interface Browser {
this.proxy = new Proxy();
return this.proxy;
}
public StorageState setStorageState() {
this.storageState = new StorageState();
return this.storageState;
public NewContextOptions withStorageState(BrowserContext.StorageState storageState) {
this.storageState = storageState;
return this;
}
}
class NewPageOptions {
@ -432,31 +407,6 @@ public interface Browser {
return this;
}
}
public class StorageState {
/**
* Optional cookies to set for context
*/
public List<Object> cookies;
/**
* Optional localStorage to set for context
*/
public List<Object> origins;
StorageState() {
}
public NewPageOptions done() {
return NewPageOptions.this;
}
public StorageState withCookies(List<Object> cookies) {
this.cookies = cookies;
return this;
}
public StorageState withOrigins(List<Object> origins) {
this.origins = origins;
return this;
}
}
/**
* Whether to automatically download all the attachments. Defaults to {@code false} where all the downloads are canceled.
*/
@ -541,7 +491,7 @@ public interface Browser {
/**
* Populates context with given storage state. This method can be used to initialize context with logged-in information obtained via browserContext.storageState().
*/
public StorageState storageState;
public BrowserContext.StorageState storageState;
public NewPageOptions withAcceptDownloads(Boolean acceptDownloads) {
this.acceptDownloads = acceptDownloads;
@ -627,9 +577,9 @@ public interface Browser {
this.proxy = new Proxy();
return this.proxy;
}
public StorageState setStorageState() {
this.storageState = new StorageState();
return this.storageState;
public NewPageOptions withStorageState(BrowserContext.StorageState storageState) {
this.storageState = storageState;
return this;
}
}
/**

View File

@ -54,6 +54,46 @@ public interface BrowserContext {
}
}
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;
}
}
class WaitForEventOptions {
public Integer timeout;
public Predicate<Event<EventType>> predicate;
@ -381,7 +421,7 @@ public interface BrowserContext {
/**
* Returns storage state for this browser context, contains current cookies and local storage snapshot.
*/
Object storageState();
StorageState storageState();
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); }
@ -408,7 +448,6 @@ public interface BrowserContext {
* <p>
*
* @param event Event name, same one would pass into {@code browserContext.on(event)}.
* @param optionsOrPredicate Either a predicate that receives an event or an options object.
* @return Promise which resolves to the event data value.
*/
Deferred<Event<EventType>> waitForEvent(EventType event, WaitForEventOptions options);

View File

@ -17,6 +17,7 @@
package com.microsoft.playwright.impl;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.microsoft.playwright.*;
@ -241,8 +242,9 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
}
@Override
public Object storageState() {
return null;
public StorageState storageState() {
JsonElement json = sendMessage("storageState");
return gson().fromJson(json, StorageState.class);
}
@Override

View File

@ -0,0 +1,71 @@
/*
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.microsoft.playwright;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import static com.microsoft.playwright.Utils.assertJsonEquals;
import static com.microsoft.playwright.Utils.mapOf;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class TestBrowserContextStorageState extends TestBase {
@Test
void shouldCaptureLocalStorage() {
page.route("**/*", route -> {
route.fulfill(new Route.FulfillResponse().withBody("<html></html>"));
});
page.navigate("https://www.example.com");
page.evaluate("localStorage['name1'] = 'value1';");
page.navigate("https://www.domain.com");
page.evaluate("localStorage['name2'] = 'value2';");
BrowserContext.StorageState storageState = context.storageState();
assertJsonEquals("[{\n" +
" origin: 'https://www.example.com',\n" +
" localStorage: [{\n" +
" name: 'name1',\n" +
" value: 'value1'\n" +
" }]\n" +
"}, {\n" +
" origin: 'https://www.domain.com',\n" +
" localStorage: [{\n" +
" name: 'name2',\n" +
" value: 'value2'\n" +
" }]\n" +
"}]", storageState.origins());
}
@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"))));
BrowserContext context = browser.newContext(new Browser.NewContextOptions().withStorageState(storageState));
Page page = context.newPage();
page.route("**/*", route -> {
route.fulfill(new Route.FulfillResponse().withBody("<html></html>"));
});
page.navigate("https://www.example.com");
Object localStorage = page.evaluate("window.localStorage");
assertEquals(mapOf("name1", "value1"), localStorage);
context.close();
}
}