mirror of
https://github.com/microsoft/playwright-java.git
synced 2025-09-08 21:01:00 +00:00
feat: geolocation (#50)
This commit is contained in:
parent
ec49645c16
commit
a721ef2456
@ -259,7 +259,10 @@ class Types {
|
||||
add("BrowserType.launchPersistentContext.options.geolocation.longitude", "number", "double");
|
||||
add("BrowserType.launchPersistentContext.options.geolocation.accuracy", "number", "double");
|
||||
|
||||
add("BrowserContext.setGeolocation.geolocation", "null|Object", "Geolocation");
|
||||
add("BrowserContext.setGeolocation.geolocation", "null|Object", "Geolocation", new Empty());
|
||||
add("Browser.newContext.options.geolocation", "Object", "Geolocation", new Empty());
|
||||
add("Browser.newPage.options.geolocation", "Object", "Geolocation", new Empty());
|
||||
add("BrowserType.launchPersistentContext.options.geolocation", "Object", "Geolocation", new Empty());
|
||||
|
||||
// Single field options
|
||||
add("Keyboard.type.options", "Object", "int", new Empty());
|
||||
|
@ -27,30 +27,6 @@ public interface Browser {
|
||||
void removeListener(EventType type, Listener<EventType> listener);
|
||||
class NewContextOptions {
|
||||
public enum ColorScheme { DARK, LIGHT, NO_PREFERENCE }
|
||||
public class Geolocation {
|
||||
public double latitude;
|
||||
public double longitude;
|
||||
public double accuracy;
|
||||
|
||||
Geolocation() {
|
||||
}
|
||||
public NewContextOptions done() {
|
||||
return NewContextOptions.this;
|
||||
}
|
||||
|
||||
public Geolocation withLatitude(double latitude) {
|
||||
this.latitude = latitude;
|
||||
return this;
|
||||
}
|
||||
public Geolocation withLongitude(double longitude) {
|
||||
this.longitude = longitude;
|
||||
return this;
|
||||
}
|
||||
public Geolocation withAccuracy(double accuracy) {
|
||||
this.accuracy = accuracy;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
public class VideoSize {
|
||||
public int width;
|
||||
public int height;
|
||||
@ -131,9 +107,9 @@ public interface Browser {
|
||||
this.timezoneId = timezoneId;
|
||||
return this;
|
||||
}
|
||||
public Geolocation setGeolocation() {
|
||||
this.geolocation = new Geolocation();
|
||||
return this.geolocation;
|
||||
public NewContextOptions withGeolocation(Geolocation geolocation) {
|
||||
this.geolocation = geolocation;
|
||||
return this;
|
||||
}
|
||||
public NewContextOptions withLocale(String locale) {
|
||||
this.locale = locale;
|
||||
@ -174,30 +150,6 @@ public interface Browser {
|
||||
}
|
||||
class NewPageOptions {
|
||||
public enum ColorScheme { DARK, LIGHT, NO_PREFERENCE }
|
||||
public class Geolocation {
|
||||
public double latitude;
|
||||
public double longitude;
|
||||
public double accuracy;
|
||||
|
||||
Geolocation() {
|
||||
}
|
||||
public NewPageOptions done() {
|
||||
return NewPageOptions.this;
|
||||
}
|
||||
|
||||
public Geolocation withLatitude(double latitude) {
|
||||
this.latitude = latitude;
|
||||
return this;
|
||||
}
|
||||
public Geolocation withLongitude(double longitude) {
|
||||
this.longitude = longitude;
|
||||
return this;
|
||||
}
|
||||
public Geolocation withAccuracy(double accuracy) {
|
||||
this.accuracy = accuracy;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
public class VideoSize {
|
||||
public int width;
|
||||
public int height;
|
||||
@ -278,9 +230,9 @@ public interface Browser {
|
||||
this.timezoneId = timezoneId;
|
||||
return this;
|
||||
}
|
||||
public Geolocation setGeolocation() {
|
||||
this.geolocation = new Geolocation();
|
||||
return this.geolocation;
|
||||
public NewPageOptions withGeolocation(Geolocation geolocation) {
|
||||
this.geolocation = geolocation;
|
||||
return this;
|
||||
}
|
||||
public NewPageOptions withLocale(String locale) {
|
||||
this.locale = locale;
|
||||
|
@ -160,24 +160,6 @@ public interface BrowserContext {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
class Geolocation {
|
||||
public int latitude;
|
||||
public int longitude;
|
||||
public Integer accuracy;
|
||||
|
||||
public Geolocation withLatitude(int latitude) {
|
||||
this.latitude = latitude;
|
||||
return this;
|
||||
}
|
||||
public Geolocation withLongitude(int longitude) {
|
||||
this.longitude = longitude;
|
||||
return this;
|
||||
}
|
||||
public Geolocation withAccuracy(Integer accuracy) {
|
||||
this.accuracy = accuracy;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
void close();
|
||||
void addCookies(List<AddCookie> cookies);
|
||||
default void addInitScript(String script) {
|
||||
|
@ -185,30 +185,6 @@ public interface BrowserType {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
public class Geolocation {
|
||||
public double latitude;
|
||||
public double longitude;
|
||||
public double accuracy;
|
||||
|
||||
Geolocation() {
|
||||
}
|
||||
public LaunchPersistentContextOptions done() {
|
||||
return LaunchPersistentContextOptions.this;
|
||||
}
|
||||
|
||||
public Geolocation withLatitude(double latitude) {
|
||||
this.latitude = latitude;
|
||||
return this;
|
||||
}
|
||||
public Geolocation withLongitude(double longitude) {
|
||||
this.longitude = longitude;
|
||||
return this;
|
||||
}
|
||||
public Geolocation withAccuracy(double accuracy) {
|
||||
this.accuracy = accuracy;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
public class VideoSize {
|
||||
public int width;
|
||||
public int height;
|
||||
@ -363,9 +339,9 @@ public interface BrowserType {
|
||||
this.timezoneId = timezoneId;
|
||||
return this;
|
||||
}
|
||||
public Geolocation setGeolocation() {
|
||||
this.geolocation = new Geolocation();
|
||||
return this.geolocation;
|
||||
public LaunchPersistentContextOptions withGeolocation(Geolocation geolocation) {
|
||||
this.geolocation = geolocation;
|
||||
return this;
|
||||
}
|
||||
public LaunchPersistentContextOptions withLocale(String locale) {
|
||||
this.locale = locale;
|
||||
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
public class Geolocation {
|
||||
public double latitude;
|
||||
public double longitude;
|
||||
public Double accuracy;
|
||||
|
||||
public Geolocation() {
|
||||
}
|
||||
|
||||
public Geolocation(double latitude, double longitude) {
|
||||
this(latitude, longitude, null);
|
||||
}
|
||||
|
||||
public Geolocation(double latitude, double longitude, Double accuracy) {
|
||||
this.latitude = latitude;
|
||||
this.longitude = longitude;
|
||||
this.accuracy = accuracy;
|
||||
}
|
||||
|
||||
public Geolocation withLatitude(double latitude) {
|
||||
this.latitude = latitude;
|
||||
return this;
|
||||
}
|
||||
public Geolocation withLongitude(double longitude) {
|
||||
this.longitude = longitude;
|
||||
return this;
|
||||
}
|
||||
public Geolocation withAccuracy(double accuracy) {
|
||||
this.accuracy = accuracy;
|
||||
return this;
|
||||
}
|
||||
}
|
@ -17,9 +17,7 @@
|
||||
package com.microsoft.playwright.impl;
|
||||
|
||||
import com.google.gson.*;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import com.microsoft.playwright.*;
|
||||
|
||||
@ -36,7 +34,7 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
final List<PageImpl> pages = new ArrayList<>();
|
||||
final Router routes = new Router();
|
||||
private boolean isClosedOrClosing;
|
||||
final Map<String, Page.Binding> bindings = new HashMap<String, Page.Binding>();
|
||||
final Map<String, Page.Binding> bindings = new HashMap<>();
|
||||
PageImpl ownerPage;
|
||||
private final ListenerCollection<EventType> listeners = new ListenerCollection<>();
|
||||
final TimeoutSettings timeoutSettings = new TimeoutSettings();
|
||||
@ -166,7 +164,15 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
|
||||
@Override
|
||||
public void grantPermissions(List<String> permissions, GrantPermissionsOptions options) {
|
||||
|
||||
if (options == null) {
|
||||
options = new GrantPermissionsOptions();
|
||||
}
|
||||
if (permissions == null) {
|
||||
permissions = Collections.emptyList();
|
||||
}
|
||||
JsonObject params = new Gson().toJsonTree(options).getAsJsonObject();
|
||||
params.add("permissions", new Gson().toJsonTree(permissions));
|
||||
sendMessage("grantPermissions", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -239,7 +245,11 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
|
||||
@Override
|
||||
public void setGeolocation(Geolocation geolocation) {
|
||||
|
||||
JsonObject params = new JsonObject();
|
||||
if (geolocation != null) {
|
||||
params.add("geolocation", new Gson().toJsonTree(geolocation));
|
||||
}
|
||||
sendMessage("setGeolocation", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* 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.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.microsoft.playwright.Page.EventType.CONSOLE;
|
||||
import static com.microsoft.playwright.Page.EventType.POPUP;
|
||||
import static com.microsoft.playwright.Utils.mapOf;
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class TestGeolocation extends TestBase {
|
||||
@Test
|
||||
void shouldWork() {
|
||||
context.grantPermissions(asList("geolocation"));
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
context.setGeolocation(new Geolocation(10, 10));
|
||||
Object geolocation = page.evaluate("() => new Promise(resolve => navigator.geolocation.getCurrentPosition(position => {\n" +
|
||||
" resolve({latitude: position.coords.latitude, longitude: position.coords.longitude});\n" +
|
||||
"}))");
|
||||
assertEquals(mapOf("latitude", 10, "longitude", 10), geolocation);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldThrowWhenInvalidLongitude() {
|
||||
try {
|
||||
context.setGeolocation(new Geolocation(10, 200));
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("geolocation.longitude: precondition -180 <= LONGITUDE <= 180 failed."));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldIsolateContexts() {
|
||||
context.grantPermissions(asList("geolocation"));
|
||||
context.setGeolocation(new Geolocation(10, 10));
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
|
||||
BrowserContext context2 = browser.newContext(new Browser.NewContextOptions()
|
||||
.withPermissions(asList("geolocation"))
|
||||
.withGeolocation(new Geolocation(20, 20)));
|
||||
Page page2 = context2.newPage();
|
||||
page2.navigate(server.EMPTY_PAGE);
|
||||
|
||||
Object geolocation = page.evaluate("() => new Promise(resolve => navigator.geolocation.getCurrentPosition(position => {\n" +
|
||||
" resolve({latitude: position.coords.latitude, longitude: position.coords.longitude});\n" +
|
||||
"}))");
|
||||
assertEquals(mapOf("latitude", 10, "longitude", 10), geolocation);
|
||||
|
||||
Object geolocation2 = page2.evaluate("() => new Promise(resolve => navigator.geolocation.getCurrentPosition(position => {\n" +
|
||||
" resolve({latitude: position.coords.latitude, longitude: position.coords.longitude});\n" +
|
||||
"}))");
|
||||
assertEquals(mapOf("latitude", 20, "longitude", 20), geolocation2);
|
||||
context2.close();
|
||||
}
|
||||
|
||||
void shouldThrowWithMissingLatitude() {
|
||||
// Not applicable in Java.
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotModifyPassedDefaultOptionsObject() {
|
||||
Geolocation geolocation = new Geolocation(10, 10);
|
||||
Browser.NewContextOptions options = new Browser.NewContextOptions().withGeolocation(geolocation);
|
||||
BrowserContext context = browser.newContext(options);
|
||||
context.setGeolocation(new Geolocation(20, 20));
|
||||
assertEquals(geolocation, options.geolocation);
|
||||
context.close();
|
||||
}
|
||||
|
||||
void shouldThrowWithMissingLongitudeInDefaultOptions() {
|
||||
// Not applicable in Java.
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldUseContextOptions() {
|
||||
Browser.NewContextOptions options = new Browser.NewContextOptions()
|
||||
.withGeolocation(new Geolocation(10, 10))
|
||||
.withPermissions(asList("geolocation"));
|
||||
BrowserContext context = browser.newContext(options);
|
||||
Page page = context.newPage();
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
Object geolocation = page.evaluate("() => new Promise(resolve => navigator.geolocation.getCurrentPosition(position => {\n" +
|
||||
" resolve({latitude: position.coords.latitude, longitude: position.coords.longitude});\n" +
|
||||
"}))");
|
||||
assertEquals(mapOf("latitude", 10, "longitude", 10), geolocation);
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void watchPositionShouldBeNotified() {
|
||||
context.grantPermissions(asList("geolocation"));
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
List<String> messages = new ArrayList<>();
|
||||
page.addListener(CONSOLE, event -> messages.add(((ConsoleMessage) event.data()).text()));
|
||||
context.setGeolocation(new Geolocation());
|
||||
page.evaluate("() => {\n" +
|
||||
" navigator.geolocation.watchPosition(pos => {\n" +
|
||||
" const coords = pos.coords;\n" +
|
||||
" console.log(`lat=${coords.latitude} lng=${coords.longitude}`);\n" +
|
||||
" }, err => {});\n" +
|
||||
"}");
|
||||
{
|
||||
Deferred<Event<Page.EventType>> deferred = page.waitForEvent(CONSOLE, event -> ((ConsoleMessage) event.data()).text().contains("lat=0 lng=10"));
|
||||
context.setGeolocation(new Geolocation(0, 10));
|
||||
deferred.get();
|
||||
}
|
||||
{
|
||||
Deferred<Event<Page.EventType>> deferred = page.waitForEvent(CONSOLE, event -> ((ConsoleMessage) event.data()).text().contains("lat=20 lng=30"));
|
||||
context.setGeolocation(new Geolocation(20, 30));
|
||||
deferred.get();
|
||||
}
|
||||
{
|
||||
Deferred<Event<Page.EventType>> deferred = page.waitForEvent(CONSOLE, event -> ((ConsoleMessage) event.data()).text().contains("lat=40 lng=50"));
|
||||
context.setGeolocation(new Geolocation(40, 50));
|
||||
deferred.get();
|
||||
}
|
||||
assertTrue(messages.contains("lat=0 lng=10"));
|
||||
assertTrue(messages.contains("lat=20 lng=30"));
|
||||
assertTrue(messages.contains("lat=40 lng=50"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldUseContextOptionsForPopup() {
|
||||
context.grantPermissions(asList("geolocation"));
|
||||
context.setGeolocation(new Geolocation(10, 10));
|
||||
Deferred<Event<Page.EventType>> popupEvent = page.waitForEvent(POPUP);
|
||||
page.evaluate("url => window['_popup'] = window.open(url)", server.PREFIX + "/geolocation.html");
|
||||
Page popup = (Page) popupEvent.get().data();
|
||||
popup.waitForLoadState();
|
||||
Object geolocation = popup.evaluate("window['geolocationPromise']");
|
||||
assertEquals(mapOf("longitude", 10, "latitude", 10), geolocation);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user