From 8e62a47f6ddedec3696e81d44cdc9b19a94d4e43 Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Fri, 12 Feb 2021 18:14:09 -0800 Subject: [PATCH] fix: generate FilePayload and setInputFiles from api.json (#286) --- .../microsoft/playwright/BrowserContext.java | 4 +- .../microsoft/playwright/ElementHandle.java | 73 ++++++++++++-- .../com/microsoft/playwright/FileChooser.java | 65 +++++++++---- .../java/com/microsoft/playwright/Frame.java | 94 +++++++++++++++++-- .../java/com/microsoft/playwright/Page.java | 94 +++++++++++++++++-- .../playwright/impl/BrowserContextImpl.java | 6 +- .../playwright/impl/ElementHandleImpl.java | 15 ++- .../playwright/impl/FileChooserImpl.java | 11 +++ .../microsoft/playwright/impl/FrameImpl.java | 14 ++- .../microsoft/playwright/impl/PageImpl.java | 12 ++- .../playwright/impl/Serialization.java | 4 +- .../com/microsoft/playwright/impl/Utils.java | 9 +- .../playwright/options/FilePayload.java | 38 ++++++++ .../microsoft/playwright/TestGeolocation.java | 8 +- .../playwright/TestPageSetInputFiles.java | 3 +- .../playwright/tools/ApiGenerator.java | 86 ++++++----------- .../com/microsoft/playwright/tools/Types.java | 4 - 17 files changed, 412 insertions(+), 128 deletions(-) create mode 100644 playwright/src/main/java/com/microsoft/playwright/options/FilePayload.java diff --git a/playwright/src/main/java/com/microsoft/playwright/BrowserContext.java b/playwright/src/main/java/com/microsoft/playwright/BrowserContext.java index eea3c013..de425a52 100644 --- a/playwright/src/main/java/com/microsoft/playwright/BrowserContext.java +++ b/playwright/src/main/java/com/microsoft/playwright/BrowserContext.java @@ -226,7 +226,7 @@ public interface BrowserContext extends AutoCloseable { * - {@code 'clipboard-write'} * - {@code 'payment-handler'} */ - default void grantPermissions(List permissions) { + default void grantPermissions(String[] permissions) { grantPermissions(permissions, null); } /** @@ -251,7 +251,7 @@ public interface BrowserContext extends AutoCloseable { * - {@code 'clipboard-write'} * - {@code 'payment-handler'} */ - void grantPermissions(List permissions, GrantPermissionsOptions options); + void grantPermissions(String[] permissions, GrantPermissionsOptions options); /** * Creates a new page in the browser context. */ diff --git a/playwright/src/main/java/com/microsoft/playwright/ElementHandle.java b/playwright/src/main/java/com/microsoft/playwright/ElementHandle.java index 5c9ba687..6cff8464 100644 --- a/playwright/src/main/java/com/microsoft/playwright/ElementHandle.java +++ b/playwright/src/main/java/com/microsoft/playwright/ElementHandle.java @@ -1068,13 +1068,6 @@ public interface ElementHandle extends JSHandle { * content. */ void selectText(SelectTextOptions options); - default void setInputFiles(Path file) { setInputFiles(file, null); } - default void setInputFiles(Path file, SetInputFilesOptions options) { setInputFiles(new Path[]{ file }, options); } - default void setInputFiles(Path[] files) { setInputFiles(files, null); } - void setInputFiles(Path[] files, SetInputFilesOptions options); - default void setInputFiles(FileChooser.FilePayload file) { setInputFiles(file, null); } - default void setInputFiles(FileChooser.FilePayload file, SetInputFilesOptions options) { setInputFiles(new FileChooser.FilePayload[]{ file }, options); } - default void setInputFiles(FileChooser.FilePayload[] files) { setInputFiles(files, null); } /** * This method expects {@code elementHandle} to point to an * [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). @@ -1082,7 +1075,71 @@ public interface ElementHandle extends JSHandle { *

Sets the value of the file input to these file paths or files. If some of the {@code filePaths} are relative paths, then they * are resolved relative to the the current working directory. For empty array, clears the selected files. */ - void setInputFiles(FileChooser.FilePayload[] files, SetInputFilesOptions options); + default void setInputFiles(Path files) { + setInputFiles(files, null); + } + /** + * This method expects {@code elementHandle} to point to an + * [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). + * + *

Sets the value of the file input to these file paths or files. If some of the {@code filePaths} are relative paths, then they + * are resolved relative to the the current working directory. For empty array, clears the selected files. + */ + void setInputFiles(Path files, SetInputFilesOptions options); + /** + * This method expects {@code elementHandle} to point to an + * [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). + * + *

Sets the value of the file input to these file paths or files. If some of the {@code filePaths} are relative paths, then they + * are resolved relative to the the current working directory. For empty array, clears the selected files. + */ + default void setInputFiles(Path[] files) { + setInputFiles(files, null); + } + /** + * This method expects {@code elementHandle} to point to an + * [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). + * + *

Sets the value of the file input to these file paths or files. If some of the {@code filePaths} are relative paths, then they + * are resolved relative to the the current working directory. For empty array, clears the selected files. + */ + void setInputFiles(Path[] files, SetInputFilesOptions options); + /** + * This method expects {@code elementHandle} to point to an + * [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). + * + *

Sets the value of the file input to these file paths or files. If some of the {@code filePaths} are relative paths, then they + * are resolved relative to the the current working directory. For empty array, clears the selected files. + */ + default void setInputFiles(FilePayload files) { + setInputFiles(files, null); + } + /** + * This method expects {@code elementHandle} to point to an + * [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). + * + *

Sets the value of the file input to these file paths or files. If some of the {@code filePaths} are relative paths, then they + * are resolved relative to the the current working directory. For empty array, clears the selected files. + */ + void setInputFiles(FilePayload files, SetInputFilesOptions options); + /** + * This method expects {@code elementHandle} to point to an + * [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). + * + *

Sets the value of the file input to these file paths or files. If some of the {@code filePaths} are relative paths, then they + * are resolved relative to the the current working directory. For empty array, clears the selected files. + */ + default void setInputFiles(FilePayload[] files) { + setInputFiles(files, null); + } + /** + * This method expects {@code elementHandle} to point to an + * [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). + * + *

Sets the value of the file input to these file paths or files. If some of the {@code filePaths} are relative paths, then they + * are resolved relative to the the current working directory. For empty array, clears the selected files. + */ + void setInputFiles(FilePayload[] files, SetInputFilesOptions options); /** * This method taps the element by performing the following steps: * 1. Wait for [actionability](./actionability.md) checks on the element, unless {@code force} option is set. diff --git a/playwright/src/main/java/com/microsoft/playwright/FileChooser.java b/playwright/src/main/java/com/microsoft/playwright/FileChooser.java index 905baf58..9f213dd6 100644 --- a/playwright/src/main/java/com/microsoft/playwright/FileChooser.java +++ b/playwright/src/main/java/com/microsoft/playwright/FileChooser.java @@ -16,6 +16,7 @@ package com.microsoft.playwright; +import com.microsoft.playwright.options.*; import java.nio.file.Path; import java.util.*; @@ -23,18 +24,6 @@ import java.util.*; * {@code FileChooser} objects are dispatched by the page in the [{@code event: Page.fileChooser}] event. */ public interface FileChooser { - class FilePayload { - public final String name; - public final String mimeType; - public final byte[] buffer; - - public FilePayload(String name, String mimeType, byte[] buffer) { - this.name = name; - this.mimeType = mimeType; - this.buffer = buffer; - } - } - class SetFilesOptions { /** * Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You can @@ -69,17 +58,53 @@ public interface FileChooser { * Returns page this file chooser belongs to. */ Page page(); - default void setFiles(Path file) { setFiles(file, null); } - default void setFiles(Path file, SetFilesOptions options) { setFiles(new Path[]{ file }, options); } - default void setFiles(Path[] files) { setFiles(files, null); } - void setFiles(Path[] files, SetFilesOptions options); - default void setFiles(FileChooser.FilePayload file) { setFiles(file, null); } - default void setFiles(FileChooser.FilePayload file, SetFilesOptions options) { setFiles(new FileChooser.FilePayload[]{ file }, options); } - default void setFiles(FileChooser.FilePayload[] files) { setFiles(files, null); } /** * Sets the value of the file input this chooser is associated with. If some of the {@code filePaths} are relative paths, then * they are resolved relative to the the current working directory. For empty array, clears the selected files. */ - void setFiles(FileChooser.FilePayload[] files, SetFilesOptions options); + default void setFiles(Path files) { + setFiles(files, null); + } + /** + * Sets the value of the file input this chooser is associated with. If some of the {@code filePaths} are relative paths, then + * they are resolved relative to the the current working directory. For empty array, clears the selected files. + */ + void setFiles(Path files, SetFilesOptions options); + /** + * Sets the value of the file input this chooser is associated with. If some of the {@code filePaths} are relative paths, then + * they are resolved relative to the the current working directory. For empty array, clears the selected files. + */ + default void setFiles(Path[] files) { + setFiles(files, null); + } + /** + * Sets the value of the file input this chooser is associated with. If some of the {@code filePaths} are relative paths, then + * they are resolved relative to the the current working directory. For empty array, clears the selected files. + */ + void setFiles(Path[] files, SetFilesOptions options); + /** + * Sets the value of the file input this chooser is associated with. If some of the {@code filePaths} are relative paths, then + * they are resolved relative to the the current working directory. For empty array, clears the selected files. + */ + default void setFiles(FilePayload files) { + setFiles(files, null); + } + /** + * Sets the value of the file input this chooser is associated with. If some of the {@code filePaths} are relative paths, then + * they are resolved relative to the the current working directory. For empty array, clears the selected files. + */ + void setFiles(FilePayload files, SetFilesOptions options); + /** + * Sets the value of the file input this chooser is associated with. If some of the {@code filePaths} are relative paths, then + * they are resolved relative to the the current working directory. For empty array, clears the selected files. + */ + default void setFiles(FilePayload[] files) { + setFiles(files, null); + } + /** + * Sets the value of the file input this chooser is associated with. If some of the {@code filePaths} are relative paths, then + * they are resolved relative to the the current working directory. For empty array, clears the selected files. + */ + void setFiles(FilePayload[] files, SetFilesOptions options); } diff --git a/playwright/src/main/java/com/microsoft/playwright/Frame.java b/playwright/src/main/java/com/microsoft/playwright/Frame.java index bd446451..bc9500b9 100644 --- a/playwright/src/main/java/com/microsoft/playwright/Frame.java +++ b/playwright/src/main/java/com/microsoft/playwright/Frame.java @@ -1647,13 +1647,6 @@ public interface Frame { * @param html HTML markup to assign to the page. */ void setContent(String html, SetContentOptions options); - default void setInputFiles(String selector, Path file) { setInputFiles(selector, file, null); } - default void setInputFiles(String selector, Path file, SetInputFilesOptions options) { setInputFiles(selector, new Path[]{ file }, options); } - default void setInputFiles(String selector, Path[] files) { setInputFiles(selector, files, null); } - void setInputFiles(String selector, Path[] files, SetInputFilesOptions options); - default void setInputFiles(String selector, FileChooser.FilePayload file) { setInputFiles(selector, file, null); } - default void setInputFiles(String selector, FileChooser.FilePayload file, SetInputFilesOptions options) { setInputFiles(selector, new FileChooser.FilePayload[]{ file }, options); } - default void setInputFiles(String selector, FileChooser.FilePayload[] files) { setInputFiles(selector, files, null); } /** * This method expects {@code selector} to point to an * [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). @@ -1664,7 +1657,92 @@ public interface Frame { * @param selector A selector to search for element. If there are multiple elements satisfying the selector, the first will be used. See * [working with selectors](./selectors.md) for more details. */ - void setInputFiles(String selector, FileChooser.FilePayload[] files, SetInputFilesOptions options); + default void setInputFiles(String selector, Path files) { + setInputFiles(selector, files, null); + } + /** + * This method expects {@code selector} to point to an + * [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). + * + *

Sets the value of the file input to these file paths or files. If some of the {@code filePaths} are relative paths, then they + * are resolved relative to the the current working directory. For empty array, clears the selected files. + * + * @param selector A selector to search for element. If there are multiple elements satisfying the selector, the first will be used. See + * [working with selectors](./selectors.md) for more details. + */ + void setInputFiles(String selector, Path files, SetInputFilesOptions options); + /** + * This method expects {@code selector} to point to an + * [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). + * + *

Sets the value of the file input to these file paths or files. If some of the {@code filePaths} are relative paths, then they + * are resolved relative to the the current working directory. For empty array, clears the selected files. + * + * @param selector A selector to search for element. If there are multiple elements satisfying the selector, the first will be used. See + * [working with selectors](./selectors.md) for more details. + */ + default void setInputFiles(String selector, Path[] files) { + setInputFiles(selector, files, null); + } + /** + * This method expects {@code selector} to point to an + * [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). + * + *

Sets the value of the file input to these file paths or files. If some of the {@code filePaths} are relative paths, then they + * are resolved relative to the the current working directory. For empty array, clears the selected files. + * + * @param selector A selector to search for element. If there are multiple elements satisfying the selector, the first will be used. See + * [working with selectors](./selectors.md) for more details. + */ + void setInputFiles(String selector, Path[] files, SetInputFilesOptions options); + /** + * This method expects {@code selector} to point to an + * [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). + * + *

Sets the value of the file input to these file paths or files. If some of the {@code filePaths} are relative paths, then they + * are resolved relative to the the current working directory. For empty array, clears the selected files. + * + * @param selector A selector to search for element. If there are multiple elements satisfying the selector, the first will be used. See + * [working with selectors](./selectors.md) for more details. + */ + default void setInputFiles(String selector, FilePayload files) { + setInputFiles(selector, files, null); + } + /** + * This method expects {@code selector} to point to an + * [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). + * + *

Sets the value of the file input to these file paths or files. If some of the {@code filePaths} are relative paths, then they + * are resolved relative to the the current working directory. For empty array, clears the selected files. + * + * @param selector A selector to search for element. If there are multiple elements satisfying the selector, the first will be used. See + * [working with selectors](./selectors.md) for more details. + */ + void setInputFiles(String selector, FilePayload files, SetInputFilesOptions options); + /** + * This method expects {@code selector} to point to an + * [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). + * + *

Sets the value of the file input to these file paths or files. If some of the {@code filePaths} are relative paths, then they + * are resolved relative to the the current working directory. For empty array, clears the selected files. + * + * @param selector A selector to search for element. If there are multiple elements satisfying the selector, the first will be used. See + * [working with selectors](./selectors.md) for more details. + */ + default void setInputFiles(String selector, FilePayload[] files) { + setInputFiles(selector, files, null); + } + /** + * This method expects {@code selector} to point to an + * [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). + * + *

Sets the value of the file input to these file paths or files. If some of the {@code filePaths} are relative paths, then they + * are resolved relative to the the current working directory. For empty array, clears the selected files. + * + * @param selector A selector to search for element. If there are multiple elements satisfying the selector, the first will be used. See + * [working with selectors](./selectors.md) for more details. + */ + void setInputFiles(String selector, FilePayload[] files, SetInputFilesOptions options); /** * This method taps an element matching {@code selector} by performing the following steps: * 1. Find an element match matching {@code selector}. If there is none, wait until a matching element is attached to the DOM. diff --git a/playwright/src/main/java/com/microsoft/playwright/Page.java b/playwright/src/main/java/com/microsoft/playwright/Page.java index 9805694c..49237ed9 100644 --- a/playwright/src/main/java/com/microsoft/playwright/Page.java +++ b/playwright/src/main/java/com/microsoft/playwright/Page.java @@ -2570,13 +2570,6 @@ public interface Page extends AutoCloseable { * @param headers An object containing additional HTTP headers to be sent with every request. All header values must be strings. */ void setExtraHTTPHeaders(Map headers); - default void setInputFiles(String selector, Path file) { setInputFiles(selector, file, null); } - default void setInputFiles(String selector, Path file, SetInputFilesOptions options) { setInputFiles(selector, new Path[]{ file }, options); } - default void setInputFiles(String selector, Path[] files) { setInputFiles(selector, files, null); } - void setInputFiles(String selector, Path[] files, SetInputFilesOptions options); - default void setInputFiles(String selector, FileChooser.FilePayload file) { setInputFiles(selector, file, null); } - default void setInputFiles(String selector, FileChooser.FilePayload file, SetInputFilesOptions options) { setInputFiles(selector, new FileChooser.FilePayload[]{ file }, options); } - default void setInputFiles(String selector, FileChooser.FilePayload[] files) { setInputFiles(selector, files, null); } /** * This method expects {@code selector} to point to an * [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). @@ -2587,7 +2580,92 @@ public interface Page extends AutoCloseable { * @param selector A selector to search for element. If there are multiple elements satisfying the selector, the first will be used. See * [working with selectors](./selectors.md) for more details. */ - void setInputFiles(String selector, FileChooser.FilePayload[] files, SetInputFilesOptions options); + default void setInputFiles(String selector, Path files) { + setInputFiles(selector, files, null); + } + /** + * This method expects {@code selector} to point to an + * [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). + * + *

Sets the value of the file input to these file paths or files. If some of the {@code filePaths} are relative paths, then they + * are resolved relative to the the current working directory. For empty array, clears the selected files. + * + * @param selector A selector to search for element. If there are multiple elements satisfying the selector, the first will be used. See + * [working with selectors](./selectors.md) for more details. + */ + void setInputFiles(String selector, Path files, SetInputFilesOptions options); + /** + * This method expects {@code selector} to point to an + * [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). + * + *

Sets the value of the file input to these file paths or files. If some of the {@code filePaths} are relative paths, then they + * are resolved relative to the the current working directory. For empty array, clears the selected files. + * + * @param selector A selector to search for element. If there are multiple elements satisfying the selector, the first will be used. See + * [working with selectors](./selectors.md) for more details. + */ + default void setInputFiles(String selector, Path[] files) { + setInputFiles(selector, files, null); + } + /** + * This method expects {@code selector} to point to an + * [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). + * + *

Sets the value of the file input to these file paths or files. If some of the {@code filePaths} are relative paths, then they + * are resolved relative to the the current working directory. For empty array, clears the selected files. + * + * @param selector A selector to search for element. If there are multiple elements satisfying the selector, the first will be used. See + * [working with selectors](./selectors.md) for more details. + */ + void setInputFiles(String selector, Path[] files, SetInputFilesOptions options); + /** + * This method expects {@code selector} to point to an + * [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). + * + *

Sets the value of the file input to these file paths or files. If some of the {@code filePaths} are relative paths, then they + * are resolved relative to the the current working directory. For empty array, clears the selected files. + * + * @param selector A selector to search for element. If there are multiple elements satisfying the selector, the first will be used. See + * [working with selectors](./selectors.md) for more details. + */ + default void setInputFiles(String selector, FilePayload files) { + setInputFiles(selector, files, null); + } + /** + * This method expects {@code selector} to point to an + * [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). + * + *

Sets the value of the file input to these file paths or files. If some of the {@code filePaths} are relative paths, then they + * are resolved relative to the the current working directory. For empty array, clears the selected files. + * + * @param selector A selector to search for element. If there are multiple elements satisfying the selector, the first will be used. See + * [working with selectors](./selectors.md) for more details. + */ + void setInputFiles(String selector, FilePayload files, SetInputFilesOptions options); + /** + * This method expects {@code selector} to point to an + * [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). + * + *

Sets the value of the file input to these file paths or files. If some of the {@code filePaths} are relative paths, then they + * are resolved relative to the the current working directory. For empty array, clears the selected files. + * + * @param selector A selector to search for element. If there are multiple elements satisfying the selector, the first will be used. See + * [working with selectors](./selectors.md) for more details. + */ + default void setInputFiles(String selector, FilePayload[] files) { + setInputFiles(selector, files, null); + } + /** + * This method expects {@code selector} to point to an + * [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). + * + *

Sets the value of the file input to these file paths or files. If some of the {@code filePaths} are relative paths, then they + * are resolved relative to the the current working directory. For empty array, clears the selected files. + * + * @param selector A selector to search for element. If there are multiple elements satisfying the selector, the first will be used. See + * [working with selectors](./selectors.md) for more details. + */ + void setInputFiles(String selector, FilePayload[] files, SetInputFilesOptions options); /** * In the case of multiple pages in a single browser, each page can have its own viewport size. However, * [{@code method: Browser.newContext}] allows to set viewport size (and more) for all pages in the context at once. diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/BrowserContextImpl.java b/playwright/src/main/java/com/microsoft/playwright/impl/BrowserContextImpl.java index e701709a..2f2aabe3 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/BrowserContextImpl.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/BrowserContextImpl.java @@ -213,16 +213,16 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext { } @Override - public void grantPermissions(List permissions, GrantPermissionsOptions options) { + public void grantPermissions(String[] permissions, GrantPermissionsOptions options) { withLogging("BrowserContext.grantPermissions", () -> grantPermissionsImpl(permissions, options)); } - private void grantPermissionsImpl(List permissions, GrantPermissionsOptions options) { + private void grantPermissionsImpl(String[] permissions, GrantPermissionsOptions options) { if (options == null) { options = new GrantPermissionsOptions(); } if (permissions == null) { - permissions = Collections.emptyList(); + permissions = new String[0]; } JsonObject params = gson().toJsonTree(options).getAsJsonObject(); params.add("permissions", gson().toJsonTree(permissions)); diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/ElementHandleImpl.java b/playwright/src/main/java/com/microsoft/playwright/impl/ElementHandleImpl.java index fcd1d599..d1e997d5 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/ElementHandleImpl.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/ElementHandleImpl.java @@ -24,6 +24,7 @@ import com.microsoft.playwright.FileChooser; import com.microsoft.playwright.Frame; import com.microsoft.playwright.options.BoundingBox; import com.microsoft.playwright.options.ElementState; +import com.microsoft.playwright.options.FilePayload; import java.nio.file.Path; import java.util.ArrayList; @@ -382,6 +383,11 @@ public class ElementHandleImpl extends JSHandleImpl implements ElementHandle { withLogging("ElementHandle.selectText", () -> selectTextImpl(options)); } + @Override + public void setInputFiles(Path files, SetInputFilesOptions options) { + setInputFiles(new Path[]{files}, options); + } + private void selectTextImpl(SelectTextOptions options) { if (options == null) { options = new SelectTextOptions(); @@ -396,11 +402,16 @@ public class ElementHandleImpl extends JSHandleImpl implements ElementHandle { } @Override - public void setInputFiles(FileChooser.FilePayload[] files, SetInputFilesOptions options) { + public void setInputFiles(FilePayload files, SetInputFilesOptions options) { + setInputFiles(new FilePayload[]{files}, options); + } + + @Override + public void setInputFiles(FilePayload[] files, SetInputFilesOptions options) { withLogging("ElementHandle.setInputFiles", () -> setInputFilesImpl(files, options)); } - void setInputFilesImpl(FileChooser.FilePayload[] files, SetInputFilesOptions options) { + void setInputFilesImpl(FilePayload[] files, SetInputFilesOptions options) { if (options == null) { options = new SetInputFilesOptions(); } diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/FileChooserImpl.java b/playwright/src/main/java/com/microsoft/playwright/impl/FileChooserImpl.java index 9377c4ba..8e3ae931 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/FileChooserImpl.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/FileChooserImpl.java @@ -19,6 +19,7 @@ package com.microsoft.playwright.impl; import com.microsoft.playwright.ElementHandle; import com.microsoft.playwright.FileChooser; import com.microsoft.playwright.Page; +import com.microsoft.playwright.options.FilePayload; import java.nio.file.Path; @@ -50,11 +51,21 @@ class FileChooserImpl implements FileChooser { return page; } + @Override + public void setFiles(Path files, SetFilesOptions options) { + setFiles(new Path[]{files}, options); + } + @Override public void setFiles(Path[] files, SetFilesOptions options) { setFiles(Utils.toFilePayloads(files), options); } + @Override + public void setFiles(FilePayload files, SetFilesOptions options) { + setFiles(new FilePayload[]{files}, options); + } + @Override public void setFiles(FilePayload[] files, SetFilesOptions options) { page.withLogging("FileChooser.setInputFiles", diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/FrameImpl.java b/playwright/src/main/java/com/microsoft/playwright/impl/FrameImpl.java index 7eda1662..4e4bd141 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/FrameImpl.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/FrameImpl.java @@ -578,6 +578,11 @@ public class FrameImpl extends ChannelOwner implements Frame { withLogging("Frame.setContent", () -> setContentImpl(html, options)); } + @Override + public void setInputFiles(String selector, Path files, SetInputFilesOptions options) { + setInputFiles(selector, new Path[] {files}, options); + } + void setContentImpl(String html, SetContentOptions options) { if (options == null) { options = new SetContentOptions(); @@ -592,16 +597,21 @@ public class FrameImpl extends ChannelOwner implements Frame { withLogging("Frame.setInputFiles", () -> setInputFilesImpl(selector, files, options)); } + @Override + public void setInputFiles(String selector, FilePayload files, SetInputFilesOptions options) { + setInputFiles(selector, new FilePayload[]{files}, options); + } + void setInputFilesImpl(String selector, Path[] files, SetInputFilesOptions options) { setInputFiles(selector, Utils.toFilePayloads(files), options); } @Override - public void setInputFiles(String selector, FileChooser.FilePayload[] files, SetInputFilesOptions options) { + public void setInputFiles(String selector, FilePayload[] files, SetInputFilesOptions options) { withLogging("Frame.setInputFiles", () -> setInputFilesImpl(selector, files, options)); } - void setInputFilesImpl(String selector, FileChooser.FilePayload[] files, SetInputFilesOptions options) { + void setInputFilesImpl(String selector, FilePayload[] files, SetInputFilesOptions options) { if (options == null) { options = new SetInputFilesOptions(); } diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/PageImpl.java b/playwright/src/main/java/com/microsoft/playwright/impl/PageImpl.java index 77c319b7..b451499a 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/PageImpl.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/PageImpl.java @@ -1021,6 +1021,11 @@ public class PageImpl extends ChannelOwner implements Page { }); } + @Override + public void setInputFiles(String selector, Path files, SetInputFilesOptions options) { + setInputFiles(selector, new Path[]{files}, options); + } + @Override public void setInputFiles(String selector, Path[] files, SetInputFilesOptions options) { withLogging("Page.setInputFiles", @@ -1028,7 +1033,12 @@ public class PageImpl extends ChannelOwner implements Page { } @Override - public void setInputFiles(String selector, FileChooser.FilePayload[] files, SetInputFilesOptions options) { + public void setInputFiles(String selector, FilePayload files, SetInputFilesOptions options) { + setInputFiles(selector, new FilePayload[]{files}, options); + } + + @Override + public void setInputFiles(String selector, FilePayload[] files, SetInputFilesOptions options) { withLogging("Page.setInputFiles", () -> mainFrame.setInputFilesImpl(selector, files, convertViaJson(options, Frame.SetInputFilesOptions.class))); } diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/Serialization.java b/playwright/src/main/java/com/microsoft/playwright/impl/Serialization.java index e5a9fb24..33e48bb5 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/Serialization.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/Serialization.java @@ -207,9 +207,9 @@ class Serialization { } } - static JsonArray toJsonArray(FileChooser.FilePayload[] files) { + static JsonArray toJsonArray(FilePayload[] files) { JsonArray jsonFiles = new JsonArray(); - for (FileChooser.FilePayload p : files) { + for (FilePayload p : files) { JsonObject jsonFile = new JsonObject(); jsonFile.addProperty("name", p.name); jsonFile.addProperty("mimeType", p.mimeType); diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/Utils.java b/playwright/src/main/java/com/microsoft/playwright/impl/Utils.java index 8decd73e..6d673a70 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/Utils.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/Utils.java @@ -19,6 +19,7 @@ package com.microsoft.playwright.impl; import com.google.gson.Gson; import com.microsoft.playwright.FileChooser; import com.microsoft.playwright.PlaywrightException; +import com.microsoft.playwright.options.FilePayload; import java.io.FileOutputStream; import java.io.IOException; @@ -111,8 +112,8 @@ class Utils { return mimeType; } - static FileChooser.FilePayload[] toFilePayloads(Path[] files) { - List payloads = new ArrayList<>(); + static FilePayload[] toFilePayloads(Path[] files) { + List payloads = new ArrayList<>(); for (Path file : files) { byte[] buffer; try { @@ -120,9 +121,9 @@ class Utils { } catch (IOException e) { throw new PlaywrightException("Failed to read from file", e); } - payloads.add(new FileChooser.FilePayload(file.getFileName().toString(), mimeType(file), buffer)); + payloads.add(new FilePayload(file.getFileName().toString(), mimeType(file), buffer)); } - return payloads.toArray(new FileChooser.FilePayload[0]); + return payloads.toArray(new FilePayload[0]); } static void writeToFile(byte[] buffer, Path path) { diff --git a/playwright/src/main/java/com/microsoft/playwright/options/FilePayload.java b/playwright/src/main/java/com/microsoft/playwright/options/FilePayload.java new file mode 100644 index 00000000..214a86fa --- /dev/null +++ b/playwright/src/main/java/com/microsoft/playwright/options/FilePayload.java @@ -0,0 +1,38 @@ +/* + * 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.options; + +public class FilePayload { + /** + * [File] name + */ + public String name; + /** + * [File] type + */ + public String mimeType; + /** + * File content + */ + public byte[] buffer; + + public FilePayload(String name, String mimeType, byte[] buffer) { + this.name = name; + this.mimeType = mimeType; + this.buffer = buffer; + } +} \ No newline at end of file diff --git a/playwright/src/test/java/com/microsoft/playwright/TestGeolocation.java b/playwright/src/test/java/com/microsoft/playwright/TestGeolocation.java index c15de764..33994eff 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestGeolocation.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestGeolocation.java @@ -30,7 +30,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; public class TestGeolocation extends TestBase { @Test void shouldWork() { - context.grantPermissions(asList("geolocation")); + context.grantPermissions(new String[]{"geolocation"}); page.navigate(server.EMPTY_PAGE); context.setGeolocation(new Geolocation(10, 10)); Object geolocation = page.evaluate("() => new Promise(resolve => navigator.geolocation.getCurrentPosition(position => {\n" + @@ -50,7 +50,7 @@ public class TestGeolocation extends TestBase { @Test void shouldIsolateContexts() { - context.grantPermissions(asList("geolocation")); + context.grantPermissions(new String[]{"geolocation"}); context.setGeolocation(new Geolocation(10, 10)); page.navigate(server.EMPTY_PAGE); @@ -107,7 +107,7 @@ public class TestGeolocation extends TestBase { @Test void watchPositionShouldBeNotified() { - context.grantPermissions(asList("geolocation")); + context.grantPermissions(new String[]{"geolocation"}); page.navigate(server.EMPTY_PAGE); List messages = new ArrayList<>(); page.onConsole(message -> messages.add(message.text())); @@ -147,7 +147,7 @@ public class TestGeolocation extends TestBase { @Test void shouldUseContextOptionsForPopup() { - context.grantPermissions(asList("geolocation")); + context.grantPermissions(new String[]{"geolocation"}); context.setGeolocation(new Geolocation(10, 10)); Page popup = page.waitForPopup(() -> page.evaluate( "url => window['_popup'] = window.open(url)", server.PREFIX + "/geolocation.html")); diff --git a/playwright/src/test/java/com/microsoft/playwright/TestPageSetInputFiles.java b/playwright/src/test/java/com/microsoft/playwright/TestPageSetInputFiles.java index bdc1150a..b97ea091 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestPageSetInputFiles.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestPageSetInputFiles.java @@ -16,6 +16,7 @@ package com.microsoft.playwright; +import com.microsoft.playwright.options.FilePayload; import org.junit.jupiter.api.Test; import java.nio.file.Path; @@ -59,7 +60,7 @@ public class TestPageSetInputFiles extends TestBase { @Test void shouldSetFromMemory() { page.setContent(""); - page.setInputFiles("input", new FileChooser.FilePayload("test.txt","text/plain","this is a test".getBytes())); + page.setInputFiles("input", new FilePayload("test.txt","text/plain","this is a test".getBytes())); assertEquals(1, page.evalOnSelector("input", "input => input.files.length")); assertEquals("test.txt", page.evalOnSelector("input", "input => input.files[0].name")); } diff --git a/tools/api-generator/src/main/java/com/microsoft/playwright/tools/ApiGenerator.java b/tools/api-generator/src/main/java/com/microsoft/playwright/tools/ApiGenerator.java index a066b979..5e30060b 100644 --- a/tools/api-generator/src/main/java/com/microsoft/playwright/tools/ApiGenerator.java +++ b/tools/api-generator/src/main/java/com/microsoft/playwright/tools/ApiGenerator.java @@ -110,6 +110,12 @@ class TypeRef extends Element { String customType; boolean isNestedClass; + private static final Map customTypeNames = new HashMap<>(); + static { + customTypeNames.put("cookies", "Cookie"); + customTypeNames.put("files", "FilePayload"); + } + TypeRef(Element parent, JsonElement jsonElement) { super(parent, true, jsonElement); @@ -191,14 +197,16 @@ class TypeRef extends Element { } if ("Object".equals(jsonObject.get("name").getAsString())) { if (customType != null) { - throw new RuntimeException("Custom type has already been created: " + customType); + // Same type maybe referenced as 'Object' in several union values, e.g. Object|Array + return; } - if (parent.jsonName.equals("cookies")) { - customType = "Cookie"; - typeScope().createTopLevelClass(customType, this, jsonElement.getAsJsonObject()); - } else if (parent instanceof Method || parent instanceof Field || (parent instanceof Param && !"options".equals(parent.jsonName))) { - customType = toTitle(parent.jsonName); - typeScope().createTopLevelClass(customType, this, jsonElement.getAsJsonObject()); + if (parent instanceof Method || parent instanceof Field || (parent instanceof Param && !"options".equals(parent.jsonName))) { + if (customTypeNames.containsKey(parent.jsonName)) { + customType = customTypeNames.get(parent.jsonName); + } else { + customType = toTitle(parent.jsonName); + } + typeScope().createTopLevelClass(customType, this, jsonObject); } else { customType = toTitle(parent.parent.jsonName) + toTitle(parent.jsonName); typeScope().createNestedClass(customType, this, jsonElement.getAsJsonObject()); @@ -294,7 +302,7 @@ class TypeRef extends Element { throw new RuntimeException("Unexpected union " + jsonPath + ": " + jsonType); } - private static String convertBuiltinType(JsonObject jsonType) { + private String convertBuiltinType(JsonObject jsonType) { String name = jsonType.get("name").getAsString(); if (jsonType.has("union")) { if (name.isEmpty()) { @@ -339,9 +347,17 @@ class TypeRef extends Element { return "Pattern"; } if ("Array".equals(name)) { - return "List<" + convertTemplateParams(jsonType) + ">"; + String elementType = convertTemplateParams(jsonType); + if (parent instanceof Param) { + // Use array instead of List as after type erasure all list are indistinguishable and wouldn't allow overloads. + return elementType + "[]"; + } + return "List<" + elementType + ">"; } if ("Object".equals(name)) { + if (customType != null) { + return customType; + } String expression = typeExpression(jsonType); if (!"Object".equals(expression) && !"Object".equals(expression)) { throw new RuntimeException("Unexpected object type: " + typeExpression(jsonType)); @@ -370,7 +386,7 @@ class TypeRef extends Element { return name; } - private static String convertTemplateParams(JsonObject jsonType) { + private String convertTemplateParams(JsonObject jsonType) { if (!jsonType.has("templates")) { return ""; } @@ -472,39 +488,6 @@ class Method extends Element { customSignature.put("BrowserContext.addCookies", new String[]{ "void addCookies(List cookies);" }); - customSignature.put("FileChooser.setFiles", new String[]{ - "default void setFiles(Path file) { setFiles(file, null); }", - "default void setFiles(Path file, SetFilesOptions options) { setFiles(new Path[]{ file }, options); }", - "default void setFiles(Path[] files) { setFiles(files, null); }", - "void setFiles(Path[] files, SetFilesOptions options);", - "default void setFiles(FileChooser.FilePayload file) { setFiles(file, null); }", - "default void setFiles(FileChooser.FilePayload file, SetFilesOptions options) { setFiles(new FileChooser.FilePayload[]{ file }, options); }", - "default void setFiles(FileChooser.FilePayload[] files) { setFiles(files, null); }", - "void setFiles(FileChooser.FilePayload[] files, SetFilesOptions options);", - }); - customSignature.put("ElementHandle.setInputFiles", new String[]{ - "default void setInputFiles(Path file) { setInputFiles(file, null); }", - "default void setInputFiles(Path file, SetInputFilesOptions options) { setInputFiles(new Path[]{ file }, options); }", - "default void setInputFiles(Path[] files) { setInputFiles(files, null); }", - "void setInputFiles(Path[] files, SetInputFilesOptions options);", - "default void setInputFiles(FileChooser.FilePayload file) { setInputFiles(file, null); }", - "default void setInputFiles(FileChooser.FilePayload file, SetInputFilesOptions options) { setInputFiles(new FileChooser.FilePayload[]{ file }, options); }", - "default void setInputFiles(FileChooser.FilePayload[] files) { setInputFiles(files, null); }", - "void setInputFiles(FileChooser.FilePayload[] files, SetInputFilesOptions options);", - }); - String[] setInputFilesWithSelector = { - "default void setInputFiles(String selector, Path file) { setInputFiles(selector, file, null); }", - "default void setInputFiles(String selector, Path file, SetInputFilesOptions options) { setInputFiles(selector, new Path[]{ file }, options); }", - "default void setInputFiles(String selector, Path[] files) { setInputFiles(selector, files, null); }", - "void setInputFiles(String selector, Path[] files, SetInputFilesOptions options);", - "default void setInputFiles(String selector, FileChooser.FilePayload file) { setInputFiles(selector, file, null); }", - "default void setInputFiles(String selector, FileChooser.FilePayload file, SetInputFilesOptions options) { setInputFiles(selector, new FileChooser.FilePayload[]{ file }, options); }", - "default void setInputFiles(String selector, FileChooser.FilePayload[] files) { setInputFiles(selector, files, null); }", - "void setInputFiles(String selector, FileChooser.FilePayload[] files, SetInputFilesOptions options);", - }; - customSignature.put("Page.setInputFiles", setInputFilesWithSelector); - customSignature.put("Frame.setInputFiles", setInputFilesWithSelector); - String[] selectOption = { "default List selectOption(String selector, String value) {", " return selectOption(selector, value, null);", @@ -875,7 +858,7 @@ class Interface extends TypeDefinition { if ("Playwright".equals(jsonName)) { output.add("import com.microsoft.playwright.impl.PlaywrightImpl;"); } - if (asList("Page", "Request", "Frame", "ElementHandle", "Browser", "BrowserContext", "BrowserType", "Mouse", "Keyboard").contains(jsonName)) { + if (asList("Page", "Request", "FileChooser", "Frame", "ElementHandle", "Browser", "BrowserContext", "BrowserType", "Mouse", "Keyboard").contains(jsonName)) { output.add("import com.microsoft.playwright.options.*;"); } if (jsonName.equals("Route")) { @@ -965,21 +948,6 @@ class Interface extends TypeDefinition { output.add(""); break; } - case "FileChooser": { - output.add(offset + "class FilePayload {"); - output.add(offset + " public final String name;"); - output.add(offset + " public final String mimeType;"); - output.add(offset + " public final byte[] buffer;"); - output.add(""); - output.add(offset + " public FilePayload(String name, String mimeType, byte[] buffer) {"); - output.add(offset + " this.name = name;"); - output.add(offset + " this.mimeType = mimeType;"); - output.add(offset + " this.buffer = buffer;"); - output.add(offset + " }"); - output.add(offset + "}"); - output.add(""); - break; - } } } } diff --git a/tools/api-generator/src/main/java/com/microsoft/playwright/tools/Types.java b/tools/api-generator/src/main/java/com/microsoft/playwright/tools/Types.java index d014423c..85e3aafe 100644 --- a/tools/api-generator/src/main/java/com/microsoft/playwright/tools/Types.java +++ b/tools/api-generator/src/main/java/com/microsoft/playwright/tools/Types.java @@ -53,12 +53,8 @@ class Types { // The method has custom signatures add("Page.selectOption.values", "Array|Array|Array|ElementHandle|Object|null|string", "String"); - add("Page.setInputFiles.files", "Array|Array|Object|path", "String"); add("Frame.selectOption.values", "Array|Array|Array|ElementHandle|Object|null|string", "String"); - add("Frame.setInputFiles.files", "Array|Array|Object|path", "String"); add("ElementHandle.selectOption.values", "Array|Array|Array|ElementHandle|Object|null|string", "String"); - add("ElementHandle.setInputFiles.files", "Array|Array|Object|path", "String"); - add("FileChooser.setFiles.files", "Array|Array|Object|path", "String"); add("Route.resume.options.postData", "Buffer|string", "byte[]", new Empty()); }