fix: interrupt listener on context close, more tests (#174)
This commit is contained in:
@@ -277,6 +277,39 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
unroute(new UrlMatcher(url), handler);
|
||||
}
|
||||
|
||||
private class WaitableContextClose<R> implements Waitable<R>, Listener<EventType> {
|
||||
private String errorMessage;
|
||||
|
||||
WaitableContextClose() {
|
||||
addListener(EventType.CLOSE, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Event<EventType> event) {
|
||||
if (EventType.CLOSE == event.type()) {
|
||||
errorMessage = "Context closed";
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDone() {
|
||||
return errorMessage != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public R get() {
|
||||
throw new PlaywrightException(errorMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
removeListener(EventType.CLOSE, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Deferred<Event<EventType>> waitForEvent(EventType event, WaitForEventOptions options) {
|
||||
if (options == null) {
|
||||
@@ -284,6 +317,7 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
}
|
||||
List<Waitable<Event<EventType>>> waitables = new ArrayList<>();
|
||||
waitables.add(new WaitableEvent<>(listeners, event, options.predicate));
|
||||
waitables.add(new WaitableContextClose<>());
|
||||
waitables.add(timeoutSettings.createWaitable(options.timeout));
|
||||
return toDeferred(new WaitableRace<>(waitables));
|
||||
}
|
||||
|
||||
@@ -56,6 +56,9 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
mainFrame = connection.getExistingObject(initializer.getAsJsonObject("mainFrame").get("guid").getAsString());
|
||||
mainFrame.page = this;
|
||||
isClosed = initializer.get("isClosed").getAsBoolean();
|
||||
if (initializer.has("viewportSize")) {
|
||||
viewport = gson().fromJson(initializer.get("viewportSize"), Viewport.class);
|
||||
}
|
||||
keyboard = new KeyboardImpl(this);
|
||||
mouse = new MouseImpl(this);
|
||||
touchscreen = new TouchscreenImpl(this);
|
||||
|
||||
@@ -16,15 +16,163 @@
|
||||
|
||||
package com.microsoft.playwright;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.util.List;
|
||||
|
||||
import static com.microsoft.playwright.BrowserContext.EventType.PAGE;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static com.microsoft.playwright.Page.EventType.POPUP;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class TestBrowserContextBasic extends TestBase {
|
||||
@Test
|
||||
void shouldCreateNewContext() {
|
||||
assertEquals(1, browser.contexts().size());
|
||||
BrowserContext context = browser.newContext();
|
||||
assertEquals(2, browser.contexts().size());
|
||||
assertTrue(browser.contexts().indexOf(context) != -1);
|
||||
assertEquals(context.browser(), browser);
|
||||
context.close();
|
||||
assertEquals(1, browser.contexts().size());
|
||||
assertEquals(context.browser(), browser);
|
||||
}
|
||||
|
||||
@Test
|
||||
void windowOpenShouldUseParentTabContext() {
|
||||
BrowserContext context = browser.newContext();
|
||||
Page page = context.newPage();
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
Deferred<Event<Page.EventType>> popupEvent = page.waitForEvent(POPUP);
|
||||
page.evaluate("url => window.open(url)", server.EMPTY_PAGE);
|
||||
Page popup = (Page) popupEvent.get().data();
|
||||
assertEquals(context, popup.context());
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldIsolateLocalStorageAndCookies() {
|
||||
// Create two incognito contexts.
|
||||
BrowserContext context1 = browser.newContext();
|
||||
BrowserContext context2 = browser.newContext();
|
||||
assertEquals(0, context1.pages().size());
|
||||
assertEquals(0, context2.pages().size());
|
||||
|
||||
// Create a page in first incognito context.
|
||||
Page page1 = context1.newPage();
|
||||
page1.navigate(server.EMPTY_PAGE);
|
||||
page1.evaluate("() => {\n" +
|
||||
" localStorage.setItem('name', 'page1');\n" +
|
||||
" document.cookie = 'name=page1';\n" +
|
||||
"}");
|
||||
|
||||
assertEquals(1, context1.pages().size());
|
||||
assertEquals(0, context2.pages().size());
|
||||
|
||||
// Create a page in second incognito context.
|
||||
Page page2 = context2.newPage();
|
||||
page2.navigate(server.EMPTY_PAGE);
|
||||
page2.evaluate("() => {\n" +
|
||||
" localStorage.setItem('name', 'page2');\n" +
|
||||
" document.cookie = 'name=page2';\n" +
|
||||
"}");
|
||||
|
||||
assertEquals(1, context1.pages().size());
|
||||
assertEquals(1, context2.pages().size());
|
||||
assertEquals(page1, context1.pages().get(0));
|
||||
assertEquals(page2, context2.pages().get(0));
|
||||
|
||||
// Make sure pages don"t share localstorage or cookies.
|
||||
assertEquals("page1", page1.evaluate("() => localStorage.getItem('name')"));
|
||||
assertEquals("name=page1", page1.evaluate("() => document.cookie"));
|
||||
assertEquals("page2", page2.evaluate("() => localStorage.getItem('name')"));
|
||||
assertEquals("name=page2", page2.evaluate("() => document.cookie"));
|
||||
|
||||
// Cleanup contexts.
|
||||
context1.close();
|
||||
context2.close();
|
||||
|
||||
assertEquals(1, browser.contexts().size());
|
||||
}
|
||||
|
||||
static void verifyViewport(Page page, int width, int height) {
|
||||
assertEquals(width, page.viewportSize().width());
|
||||
assertEquals(height, page.viewportSize().height());
|
||||
assertEquals(width, page.evaluate("window.innerWidth"));
|
||||
assertEquals(height, page.evaluate("window.innerHeight"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldPropagateDefaultViewportToThePage() {
|
||||
BrowserContext context = browser.newContext(new Browser.NewContextOptions().withViewport(456, 789));
|
||||
Page page = context.newPage();
|
||||
verifyViewport(page, 456, 789);
|
||||
context.close();
|
||||
}
|
||||
|
||||
void shouldMakeACopyOfDefaultViewport() {
|
||||
// Doesn't make sense in Java.
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRespectDeviceScaleFactor() {
|
||||
BrowserContext context = browser.newContext(new Browser.NewContextOptions().withDeviceScaleFactor(3));
|
||||
Page page = context.newPage();
|
||||
assertEquals(3, page.evaluate("window.devicePixelRatio"));
|
||||
context.close();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@Disabled("TODO: supported null viewport option")
|
||||
void shouldNotAllowDeviceScaleFactorWithNullViewport() {
|
||||
try {
|
||||
browser.newContext(new Browser.NewContextOptions().withDeviceScaleFactor(1));
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("\"deviceScaleFactor\" option is not supported with null \"viewport\""));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled("TODO: supported null viewport option")
|
||||
void shouldNotAllowIsMobileWithNullViewport() {
|
||||
try {
|
||||
browser.newContext(new Browser.NewContextOptions().withIsMobile(true));
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("\"isMobile\" option is not supported with null \"viewport\""));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void closeShouldWorkForEmptyContext() {
|
||||
BrowserContext context = browser.newContext();
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void closeShouldAbortWaitForEvent() {
|
||||
BrowserContext context = browser.newContext();
|
||||
Deferred<Event<BrowserContext.EventType>> pageEvent = context.waitForEvent(PAGE);
|
||||
context.close();
|
||||
try {
|
||||
pageEvent.get();
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Context closed"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void closeShouldBeCallableTwice() {
|
||||
BrowserContext context = browser.newContext();
|
||||
context.close();
|
||||
context.close();
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotReportFramelessPagesOnError() {
|
||||
BrowserContext context = browser.newContext();
|
||||
@@ -46,4 +194,88 @@ public class TestBrowserContextBasic extends TestBase {
|
||||
assertNotNull(popup[0].mainFrame());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnAllOfThePages() {
|
||||
BrowserContext context = browser.newContext();
|
||||
Page page = context.newPage();
|
||||
Page second = context.newPage();
|
||||
List<Page> allPages = context.pages();
|
||||
assertEquals(2, allPages.size());
|
||||
assertTrue(allPages.contains(page));
|
||||
assertTrue(allPages.contains(second));
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldCloseAllBelongingPagesOnceClosingContext() {
|
||||
BrowserContext context = browser.newContext();
|
||||
context.newPage();
|
||||
assertEquals(1, context.pages().size());
|
||||
context.close();
|
||||
assertEquals(0, context.pages().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldDisableJavascript() {
|
||||
{
|
||||
BrowserContext context = browser.newContext(new Browser.NewContextOptions().withJavaScriptEnabled(false));
|
||||
Page page = context.newPage();
|
||||
page.navigate("data:text/html, <script>var something = 'forbidden'</script>");
|
||||
try {
|
||||
page.evaluate("something");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
if (isWebKit())
|
||||
assertTrue(e.getMessage().contains("Can\'t find variable: something"));
|
||||
else
|
||||
assertTrue(e.getMessage().contains("something is not defined"));
|
||||
}
|
||||
context.close();
|
||||
}
|
||||
|
||||
{
|
||||
BrowserContext context = browser.newContext();
|
||||
Page page = context.newPage();
|
||||
page.navigate("data:text/html, <script>var something = 'forbidden'</script>");
|
||||
assertEquals("forbidden", page.evaluate("something"));
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldBeAbleToNavigateAfterDisablingJavascript() {
|
||||
BrowserContext context = browser.newContext(new Browser.NewContextOptions().withJavaScriptEnabled(false));
|
||||
Page page = context.newPage();
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldWorkWithOfflineOption() {
|
||||
BrowserContext context = browser.newContext(new Browser.NewContextOptions().withOffline(true));
|
||||
Page page = context.newPage();
|
||||
try {
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
}
|
||||
|
||||
context.setOffline(false);
|
||||
Response response = page.navigate(server.EMPTY_PAGE);
|
||||
assertEquals(200, response.status());
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldEmulateNavigatorOnLine() {
|
||||
BrowserContext context = browser.newContext();
|
||||
Page page = context.newPage();
|
||||
assertEquals(true, page.evaluate("() => window.navigator.onLine"));
|
||||
context.setOffline(true);
|
||||
assertEquals(false, page.evaluate("() => window.navigator.onLine"));
|
||||
context.setOffline(false);
|
||||
assertEquals(true, page.evaluate("() => window.navigator.onLine"));
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user