1
0
mirror of synced 2026-08-05 15:06:54 +00:00

fix(video): make Video.path work (#193)

This commit is contained in:
Yury Semikhatsky
2021-01-06 15:12:01 -08:00
committed by GitHub
parent 13d7ee6b44
commit fc5bd76334
9 changed files with 115 additions and 8 deletions
@@ -16,6 +16,7 @@
package com.microsoft.playwright;
import java.nio.file.Path;
import java.util.*;
/**
@@ -26,6 +27,6 @@ public interface Video {
/**
* Returns the file system path this video will be recorded to. The video is guaranteed to be written to the filesystem upon closing the browser context.
*/
String path();
Path path();
}
@@ -25,6 +25,7 @@ import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Predicate;
@@ -43,8 +44,9 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
PageImpl ownerPage;
private final ListenerCollection<EventType> listeners = new ListenerCollection<>();
final TimeoutSettings timeoutSettings = new TimeoutSettings();
Path videosDir;
protected BrowserContextImpl(ChannelOwner parent, String type, String guid, JsonObject initializer) {
BrowserContextImpl(ChannelOwner parent, String type, String guid, JsonObject initializer) {
super(parent, type, guid, initializer);
if (parent instanceof BrowserImpl) {
browser = (BrowserImpl) parent;
@@ -88,6 +88,9 @@ class BrowserImpl extends ChannelOwner implements Browser {
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
JsonElement result = sendMessage("newContext", params);
BrowserContextImpl context = connection.getExistingObject(result.getAsJsonObject().getAsJsonObject("context").get("guid").getAsString());
if (options.recordVideo != null) {
context.videosDir = options.recordVideo.dir;
}
contexts.add(context);
return context;
}
@@ -47,14 +47,18 @@ class BrowserTypeImpl extends ChannelOwner implements BrowserType {
@Override
public BrowserContext launchPersistentContext(Path userDataDir, LaunchPersistentContextOptions options) {
public BrowserContextImpl launchPersistentContext(Path userDataDir, LaunchPersistentContextOptions options) {
if (options == null) {
options = new LaunchPersistentContextOptions();
}
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
params.addProperty("userDataDir", userDataDir.toString());
JsonObject json = sendMessage("launchPersistentContext", params).getAsJsonObject();
return connection.getExistingObject(json.getAsJsonObject("context").get("guid").getAsString());
BrowserContextImpl context = connection.getExistingObject(json.getAsJsonObject("context").get("guid").getAsString());
if (options.recordVideo != null) {
context.videosDir = options.recordVideo.dir;
}
return context;
}
public String name() {
@@ -49,6 +49,7 @@ public class PageImpl extends ChannelOwner implements Page {
private boolean isClosed;
final Set<Worker> workers = new HashSet<>();
private final TimeoutSettings timeoutSettings;
private VideoImpl video;
PageImpl(ChannelOwner parent, String type, String guid, JsonObject initializer) {
super(parent, type, guid, initializer);
@@ -168,6 +169,8 @@ public class PageImpl extends ChannelOwner implements Page {
if (!handled) {
route.continue_();
}
} else if ("video".equals(event)) {
video().setRelativePath(params.get("relativePath").getAsString());
} else if ("pageError".equals(event)) {
SerializedError error = gson().fromJson(params.getAsJsonObject("error"), SerializedError.class);
listeners.notify(EventType.PAGEERROR, new ErrorImpl(error));
@@ -296,7 +299,7 @@ public class PageImpl extends ChannelOwner implements Page {
}
@Override
public BrowserContext context() {
public BrowserContextImpl context() {
return browserContext;
}
@@ -705,8 +708,19 @@ public class PageImpl extends ChannelOwner implements Page {
}
@Override
public Video video() {
return null;
public VideoImpl video() {
if (video != null) {
return video;
}
if (browserContext.videosDir == null) {
return null;
}
video = new VideoImpl(this);
// In case of persistent profile, we already have it.
if (initializer.has("videoRelativePath")) {
video.setRelativePath(initializer.get("videoRelativePath").getAsString());
}
return video;
}
@Override
@@ -0,0 +1,42 @@
/*
* 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.impl;
import com.microsoft.playwright.Video;
import java.nio.file.Path;
class VideoImpl implements Video {
private final PageImpl page;
private Path fullPath;
VideoImpl(PageImpl page) {
this.page = page;
}
void setRelativePath(String path) {
fullPath = page.context().videosDir.resolve(path);
}
@Override
public Path path() {
while (fullPath == null) {
page.connection.processOneMessage();
}
return fullPath;
}
}
@@ -0,0 +1,40 @@
/*
* 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 org.junit.jupiter.api.io.TempDir;
import java.nio.file.Files;
import java.nio.file.Path;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class TestScreencast extends TestBase {
@Test
void shouldExposeVideoPath(@TempDir Path videosDir) {
BrowserContext context = browser.newContext(new Browser.NewContextOptions()
.setRecordVideo().withDir(videosDir).withSize(320, 240).done()
.withViewport(320, 240));
Page page = context.newPage();
page.evaluate("() => document.body.style.backgroundColor = 'red'");
Path path = page.video().path();
assertTrue(path.startsWith(videosDir));
context.close();
assertTrue(Files.exists(path));
};
}
@@ -801,7 +801,7 @@ class Interface extends TypeDefinition {
if ("Download".equals(jsonName)) {
output.add("import java.io.InputStream;");
}
if (asList("Page", "Frame", "ElementHandle", "FileChooser", "Browser", "BrowserContext", "BrowserType", "Download", "Route", "Selectors").contains(jsonName)) {
if (asList("Page", "Frame", "ElementHandle", "FileChooser", "Browser", "BrowserContext", "BrowserType", "Download", "Route", "Selectors", "Video").contains(jsonName)) {
output.add("import java.nio.file.Path;");
}
output.add("import java.util.*;");
@@ -121,6 +121,7 @@ class Types {
add("BrowserType.launch.options.downloadsPath", "string", "Path");
add("BrowserContext.storageState.options.path", "string", "Path");
add("ChromiumBrowser.startTracing.options.path", "string", "Path");
add("Video.path", "Promise<string>", "Path");
// Route
add("BrowserContext.route.handler", "function(Route, Request)", "Consumer<Route>");