From b1ac694d294770e17246cd02838e8ed0cebab441 Mon Sep 17 00:00:00 2001 From: Umair Chagani Date: Tue, 22 Aug 2023 22:20:26 -0400 Subject: [PATCH 1/8] feat(soft-assertions): Implement soft assertions for playwright-java --- playwright/pom.xml | 4 + .../microsoft/playwright/BrowserContext.java | 10 + .../com/microsoft/playwright/Download.java | 17 +- .../com/microsoft/playwright/PageError.java | 47 ++++ .../playwright/assertions/SoftAssertions.java | 114 ++++++++ .../impl/APIResponseAssertionsImpl.java | 2 +- .../impl/APIResponseAssertionsImplProxy.java | 45 ++++ .../impl/LocatorAssertionsImpl.java | 2 +- .../impl/LocatorAssertionsImplProxy.java | 195 ++++++++++++++ .../playwright/impl/PageAssertionsImpl.java | 2 +- .../impl/PageAssertionsImplProxy.java | 61 +++++ .../playwright/impl/SoftAssertionsBase.java | 38 +++ .../playwright/impl/SoftAssertionsImpl.java | 74 ++++++ .../TestSoftAPIResponseAssertions.java | 46 ++++ .../playwright/TestSoftAssertions.java | 49 ++++ .../playwright/TestSoftLocatorAssertions.java | 248 ++++++++++++++++++ .../playwright/TestSoftPageAssertions.java | 66 +++++ .../java/com/microsoft/playwright/Utils.java | 14 + pom.xml | 13 + scripts/CLI_VERSION | 2 +- .../playwright/tools/ApiGenerator.java | 12 + 21 files changed, 1052 insertions(+), 9 deletions(-) create mode 100644 playwright/src/main/java/com/microsoft/playwright/PageError.java create mode 100644 playwright/src/main/java/com/microsoft/playwright/assertions/SoftAssertions.java create mode 100644 playwright/src/main/java/com/microsoft/playwright/impl/APIResponseAssertionsImplProxy.java create mode 100644 playwright/src/main/java/com/microsoft/playwright/impl/LocatorAssertionsImplProxy.java create mode 100644 playwright/src/main/java/com/microsoft/playwright/impl/PageAssertionsImplProxy.java create mode 100644 playwright/src/main/java/com/microsoft/playwright/impl/SoftAssertionsBase.java create mode 100644 playwright/src/main/java/com/microsoft/playwright/impl/SoftAssertionsImpl.java create mode 100644 playwright/src/test/java/com/microsoft/playwright/TestSoftAPIResponseAssertions.java create mode 100644 playwright/src/test/java/com/microsoft/playwright/TestSoftAssertions.java create mode 100644 playwright/src/test/java/com/microsoft/playwright/TestSoftLocatorAssertions.java create mode 100644 playwright/src/test/java/com/microsoft/playwright/TestSoftPageAssertions.java diff --git a/playwright/pom.xml b/playwright/pom.xml index 30db61b7b..b1706c8ce 100644 --- a/playwright/pom.xml +++ b/playwright/pom.xml @@ -73,5 +73,9 @@ com.microsoft.playwright driver-bundle + + org.mockito + mockito-junit-jupiter + diff --git a/playwright/src/main/java/com/microsoft/playwright/BrowserContext.java b/playwright/src/main/java/com/microsoft/playwright/BrowserContext.java index 35338811e..6eb2f8daf 100644 --- a/playwright/src/main/java/com/microsoft/playwright/BrowserContext.java +++ b/playwright/src/main/java/com/microsoft/playwright/BrowserContext.java @@ -127,6 +127,16 @@ public interface BrowserContext extends AutoCloseable { */ void offPage(Consumer handler); + /** + * Emitted when unhandled exceptions occur on any pages created through this context. To only listen for {@code pageError} + * events from a particular page, use {@link Page#onPageError Page.onPageError()}. + */ + void onPageError(Consumer handler); + /** + * Removes handler that was previously added with {@link #onPageError onPageError(handler)}. + */ + void offPageError(Consumer handler); + /** * Emitted when a request is issued from any pages created through this context. The [request] object is read-only. To only * listen for requests from a particular page, use {@link Page#onRequest Page.onRequest()}. diff --git a/playwright/src/main/java/com/microsoft/playwright/Download.java b/playwright/src/main/java/com/microsoft/playwright/Download.java index ca8cbc6f7..b51051150 100644 --- a/playwright/src/main/java/com/microsoft/playwright/Download.java +++ b/playwright/src/main/java/com/microsoft/playwright/Download.java @@ -24,14 +24,16 @@ * *

All the downloaded files belonging to the browser context are deleted when the browser context is closed. * - *

Download event is emitted once the download starts. Download path becomes available once download completes: + *

Download event is emitted once the download starts. Download path becomes available once download completes. *

{@code
- * // wait for download to start
+ * // Wait for the download to start
  * Download download = page.waitForDownload(() -> {
- *   page.getByText("Download file").click();
+ *     // Perform the action that initiates download
+ *     page.getByText("Download file").click();
  * });
- * // wait for download to complete
- * Path path = download.path();
+ *
+ * // Wait for the download process to complete and save the downloaded file somewhere
+ * download.saveAs(Paths.get("/path/to/save/at/", download.suggestedFilename()));
  * }
*/ public interface Download { @@ -80,6 +82,11 @@ public interface Download { * Copy the download to a user-specified path. It is safe to call this method while the download is still in progress. Will * wait for the download to finish if necessary. * + *

**Usage** + *

{@code
+   * download.saveAs(Paths.get("/path/to/save/at/", download.suggestedFilename()));
+   * }
+ * * @param path Path where the download should be copied. * @since v1.8 */ diff --git a/playwright/src/main/java/com/microsoft/playwright/PageError.java b/playwright/src/main/java/com/microsoft/playwright/PageError.java new file mode 100644 index 000000000..45a19c6af --- /dev/null +++ b/playwright/src/main/java/com/microsoft/playwright/PageError.java @@ -0,0 +1,47 @@ +/* + * 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; + + +/** + * {@code PageError} class represents objects created by context when there are unhandled execeptions thrown on the pages + * and dispatched via the {@link BrowserContext#onPageError BrowserContext.onPageError()} event. + *
{@code
+ * // Log all uncaught errors to the terminal
+ * context.onPageError(pagerror -> {
+ *   System.out.println("Uncaught exception: " + pagerror.error());
+ * });
+ *
+ * // Navigate to a page with an exception.
+ * page.navigate("data:text/html,");
+ * }
+ */ +public interface PageError { + /** + * The page that produced this unhandled exception, if any. + * + * @since v1.38 + */ + Page page(); + /** + * Unhandled error that was thrown. + * + * @since v1.38 + */ + Error error(); +} + diff --git a/playwright/src/main/java/com/microsoft/playwright/assertions/SoftAssertions.java b/playwright/src/main/java/com/microsoft/playwright/assertions/SoftAssertions.java new file mode 100644 index 000000000..618cc7a0b --- /dev/null +++ b/playwright/src/main/java/com/microsoft/playwright/assertions/SoftAssertions.java @@ -0,0 +1,114 @@ +/* + * 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.assertions; + +import com.microsoft.playwright.impl.SoftAssertionsImpl; +import com.microsoft.playwright.APIResponse; +import com.microsoft.playwright.Locator; +import com.microsoft.playwright.Page; + +/** + * The {@code SoftAssertions} class provides assertion methods that can be used to make multiple assertions without failing + * the test immediately. + *
{@code
+ * ...
+ * import com.microsoft.playwright.assertions.SoftAssertions;
+ *
+ * public class TestPage {
+ *   ...
+ *   @Test
+ *   void hasUrlTextPass() {
+ *     SoftAssertions softly = SoftAssertions.create();
+ *     page.getByText("Sign in").click();
+ *     softly.assertThat(page).hasURL(Pattern.compile(".*\/login"));
+ *     softly.assertAll();
+ *   }
+ * }
+ * }
+ */ +public interface SoftAssertions { + /** + * Creates a {@code SoftAssertions} object. + * + *

**Usage** + *

{@code
+   * SoftAssertions softly = SoftAssertions.create();
+   * }
+ * + * @since v1.38 + */ + static SoftAssertions create() { + return new SoftAssertionsImpl(); + } + /** + * Creates a {@code LocatorAssertions} object for the given {@code Locator}. + * + *

**Usage** + *

{@code
+   * SoftAssertions softly = SoftAssertions.create();
+   * ...
+   * softly.assertThat(locator).isVisible();
+   * }
+ * + * @param locator {@code Locator} object to use for assertions. + * @since v1.38 + */ + LocatorAssertions assertThat(Locator locator); + /** + * Creates a {@code PageAssertions} object for the given {@code Page}. + * + *

**Usage** + *

{@code
+   * SoftAssertions softly = SoftAssertions.create();
+   * ...
+   * softly.assertThat(page).hasTitle("News");
+   * }
+ * + * @param page {@code Page} object to use for assertions. + * @since v1.38 + */ + PageAssertions assertThat(Page page); + /** + * Creates a {@code APIResponseAssertions} object for the given {@code APIResponse}. + * + *

**Usage** + *

{@code
+   * SoftAssertions softly = SoftAssertions.create();
+   * ...
+   * softly.assertThat(response).isOK();
+   * }
+ * + * @param response {@code APIResponse} object to use for assertions. + * @since v1.38 + */ + APIResponseAssertions assertThat(APIResponse response); + /** + * Runs all the assertions have been executed for this {@code SoftAssertions} object. If any assertions fail, this method + * throws an AssertionFailedError with the details of all the failed assertions. + * + *

**Usage** + *

{@code
+   * SoftAssertions softly = SoftAssertions.create();
+   * ...
+   * softly.assertAll();
+   * }
+ * + * @since v1.38 + */ + void assertAll(); +} + diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/APIResponseAssertionsImpl.java b/playwright/src/main/java/com/microsoft/playwright/impl/APIResponseAssertionsImpl.java index 67d7dfc57..2893c7c11 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/APIResponseAssertionsImpl.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/APIResponseAssertionsImpl.java @@ -37,7 +37,7 @@ public APIResponseAssertionsImpl(APIResponse response) { } @Override - public APIResponseAssertions not() { + public APIResponseAssertionsImpl not() { return new APIResponseAssertionsImpl(actual, !isNot); } diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/APIResponseAssertionsImplProxy.java b/playwright/src/main/java/com/microsoft/playwright/impl/APIResponseAssertionsImplProxy.java new file mode 100644 index 000000000..049e6e009 --- /dev/null +++ b/playwright/src/main/java/com/microsoft/playwright/impl/APIResponseAssertionsImplProxy.java @@ -0,0 +1,45 @@ +/* + * 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.APIResponse; +import com.microsoft.playwright.assertions.APIResponseAssertions; + +import java.util.List; + +public class APIResponseAssertionsImplProxy extends SoftAssertionsBase implements APIResponseAssertions { + private final APIResponseAssertionsImpl apiResponseAssertionsImpl; + + APIResponseAssertionsImplProxy(APIResponse response, List results) { + this(results, new APIResponseAssertionsImpl(response)); + } + + public APIResponseAssertionsImplProxy(List results, APIResponseAssertionsImpl apiResponseAssertionsImpl) { + super(results); + this.apiResponseAssertionsImpl = apiResponseAssertionsImpl; + } + + @Override + public APIResponseAssertions not() { + return new APIResponseAssertionsImplProxy(super.results, apiResponseAssertionsImpl.not()); + } + + @Override + public void isOK() { + assertAndCaptureResult(apiResponseAssertionsImpl::isOK); + } +} diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/LocatorAssertionsImpl.java b/playwright/src/main/java/com/microsoft/playwright/impl/LocatorAssertionsImpl.java index 3b8213188..144b613a8 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/LocatorAssertionsImpl.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/LocatorAssertionsImpl.java @@ -353,7 +353,7 @@ private void expectTrue(String expression, String message, FrameExpectOptions op } @Override - public LocatorAssertions not() { + public LocatorAssertionsImpl not() { return new LocatorAssertionsImpl(actualLocator, !isNot); } diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/LocatorAssertionsImplProxy.java b/playwright/src/main/java/com/microsoft/playwright/impl/LocatorAssertionsImplProxy.java new file mode 100644 index 000000000..4b8a18e54 --- /dev/null +++ b/playwright/src/main/java/com/microsoft/playwright/impl/LocatorAssertionsImplProxy.java @@ -0,0 +1,195 @@ +package com.microsoft.playwright.impl; + +import com.microsoft.playwright.Locator; +import com.microsoft.playwright.assertions.LocatorAssertions; + +import java.util.List; +import java.util.regex.Pattern; + +public class LocatorAssertionsImplProxy extends SoftAssertionsBase implements LocatorAssertions { + private final LocatorAssertionsImpl locatorAssertionsImpl; + + public LocatorAssertionsImplProxy(Locator locator, List results) { + this(results, new LocatorAssertionsImpl(locator)); + } + + public LocatorAssertionsImplProxy(List results, LocatorAssertionsImpl locatorAssertionsImpl) { + super(results); + this.locatorAssertionsImpl = locatorAssertionsImpl; + } + + @Override + public LocatorAssertions not() { + return new LocatorAssertionsImplProxy(super.results, locatorAssertionsImpl.not()); + } + + @Override + public void isAttached(IsAttachedOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.isAttached(options)); + } + + @Override + public void isChecked(IsCheckedOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.isChecked(options)); + } + + @Override + public void isDisabled(IsDisabledOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.isDisabled(options)); + } + + @Override + public void isEditable(IsEditableOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.isEditable(options)); + } + + @Override + public void isEmpty(IsEmptyOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.isEmpty(options)); + } + + @Override + public void isEnabled(IsEnabledOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.isEnabled(options)); + } + + @Override + public void isFocused(IsFocusedOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.isFocused(options)); + } + + @Override + public void isHidden(IsHiddenOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.isHidden(options)); + } + + @Override + public void isInViewport(IsInViewportOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.isInViewport(options)); + } + + @Override + public void isVisible(IsVisibleOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.isVisible(options)); + } + + @Override + public void containsText(String expected, ContainsTextOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.containsText(expected, options)); + } + + @Override + public void containsText(Pattern expected, ContainsTextOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.containsText(expected, options)); + } + + @Override + public void containsText(String[] expected, ContainsTextOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.containsText(expected, options)); + } + + @Override + public void containsText(Pattern[] expected, ContainsTextOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.containsText(expected, options)); + } + + @Override + public void hasAttribute(String name, String value, HasAttributeOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.hasAttribute(name, value, options)); + } + + @Override + public void hasAttribute(String name, Pattern value, HasAttributeOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.hasAttribute(name, value, options)); + } + + @Override + public void hasClass(String expected, HasClassOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.hasClass(expected, options)); + } + + @Override + public void hasClass(Pattern expected, HasClassOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.hasClass(expected, options)); + } + + @Override + public void hasClass(String[] expected, HasClassOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.hasClass(expected, options)); + } + + @Override + public void hasClass(Pattern[] expected, HasClassOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.hasClass(expected, options)); + } + + @Override + public void hasCount(int count, HasCountOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.hasCount(count, options)); + } + + @Override + public void hasCSS(String name, String value, HasCSSOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.hasCSS(name, value, options)); + } + + @Override + public void hasCSS(String name, Pattern value, HasCSSOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.hasCSS(name, value, options)); + } + + @Override + public void hasId(String id, HasIdOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.hasId(id, options)); + } + + @Override + public void hasId(Pattern id, HasIdOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.hasId(id, options)); + } + + @Override + public void hasJSProperty(String name, Object value, HasJSPropertyOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.hasJSProperty(name, value, options)); + } + + @Override + public void hasText(String expected, HasTextOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.hasText(expected, options)); + } + + @Override + public void hasText(Pattern expected, HasTextOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.hasText(expected, options)); + } + + @Override + public void hasText(String[] expected, HasTextOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.hasText(expected, options)); + } + + @Override + public void hasText(Pattern[] expected, HasTextOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.hasText(expected, options)); + } + + @Override + public void hasValue(String value, HasValueOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.hasValue(value, options)); + } + + @Override + public void hasValue(Pattern value, HasValueOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.hasValue(value, options)); + } + + @Override + public void hasValues(String[] values, HasValuesOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.hasValues(values, options)); + } + + @Override + public void hasValues(Pattern[] values, HasValuesOptions options) { + assertAndCaptureResult(() -> locatorAssertionsImpl.hasValues(values, options)); + } +} diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/PageAssertionsImpl.java b/playwright/src/main/java/com/microsoft/playwright/impl/PageAssertionsImpl.java index ee6e71588..616b282d6 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/PageAssertionsImpl.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/PageAssertionsImpl.java @@ -67,7 +67,7 @@ public void hasURL(Pattern pattern, HasURLOptions options) { } @Override - public PageAssertions not() { + public PageAssertionsImpl not() { return new PageAssertionsImpl(actualPage, !isNot); } } diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/PageAssertionsImplProxy.java b/playwright/src/main/java/com/microsoft/playwright/impl/PageAssertionsImplProxy.java new file mode 100644 index 000000000..60eaebf0c --- /dev/null +++ b/playwright/src/main/java/com/microsoft/playwright/impl/PageAssertionsImplProxy.java @@ -0,0 +1,61 @@ +/* + * 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.Page; +import com.microsoft.playwright.assertions.PageAssertions; + +import java.util.List; +import java.util.regex.Pattern; + +public class PageAssertionsImplProxy extends SoftAssertionsBase implements PageAssertions { + private final PageAssertionsImpl pageAssertionsImpl; + + PageAssertionsImplProxy(Page page, List results) { + this(results, new PageAssertionsImpl(page)); + } + + public PageAssertionsImplProxy(List results, PageAssertionsImpl pageAssertionsImpl) { + super(results); + this.pageAssertionsImpl = pageAssertionsImpl; + } + + @Override + public PageAssertions not() { + return new PageAssertionsImplProxy(super.results, pageAssertionsImpl.not()); + } + + @Override + public void hasTitle(String titleOrRegExp, HasTitleOptions options) { + assertAndCaptureResult(() -> pageAssertionsImpl.hasTitle(titleOrRegExp, options)); + } + + @Override + public void hasTitle(Pattern titleOrRegExp, HasTitleOptions options) { + assertAndCaptureResult(() -> pageAssertionsImpl.hasTitle(titleOrRegExp, options)); + } + + @Override + public void hasURL(String urlOrRegExp, HasURLOptions options) { + assertAndCaptureResult(() -> pageAssertionsImpl.hasURL(urlOrRegExp, options)); + } + + @Override + public void hasURL(Pattern urlOrRegExp, HasURLOptions options) { + assertAndCaptureResult(() -> pageAssertionsImpl.hasURL(urlOrRegExp, options)); + } +} diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/SoftAssertionsBase.java b/playwright/src/main/java/com/microsoft/playwright/impl/SoftAssertionsBase.java new file mode 100644 index 000000000..917cd629b --- /dev/null +++ b/playwright/src/main/java/com/microsoft/playwright/impl/SoftAssertionsBase.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.impl; + +import com.microsoft.playwright.PlaywrightException; +import org.opentest4j.AssertionFailedError; + +import java.util.List; + +class SoftAssertionsBase { + final List results; + + SoftAssertionsBase(List results) { + this.results = results; + } + + void assertAndCaptureResult(Runnable assertion) { + try { + assertion.run(); + } catch (AssertionFailedError | PlaywrightException failure) { + results.add(failure); + } + } +} diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/SoftAssertionsImpl.java b/playwright/src/main/java/com/microsoft/playwright/impl/SoftAssertionsImpl.java new file mode 100644 index 000000000..034e08eed --- /dev/null +++ b/playwright/src/main/java/com/microsoft/playwright/impl/SoftAssertionsImpl.java @@ -0,0 +1,74 @@ +/* + * 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.APIResponse; +import com.microsoft.playwright.Locator; +import com.microsoft.playwright.Page; +import com.microsoft.playwright.assertions.APIResponseAssertions; +import com.microsoft.playwright.assertions.LocatorAssertions; +import com.microsoft.playwright.assertions.PageAssertions; +import com.microsoft.playwright.assertions.SoftAssertions; +import org.opentest4j.AssertionFailedError; + +import java.util.ArrayList; +import java.util.List; + +public class SoftAssertionsImpl implements SoftAssertions { + final List results; + + public SoftAssertionsImpl() { + this.results = new ArrayList<>(); + } + + @Override + public LocatorAssertions assertThat(Locator locator) { + return new LocatorAssertionsImplProxy(locator, results); + } + + @Override + public PageAssertions assertThat(Page page) { + return new PageAssertionsImplProxy(page, results); + } + + @Override + public APIResponseAssertions assertThat(APIResponse response) { + return new APIResponseAssertionsImplProxy(response, results); + } + + @Override + public void assertAll() { + if (!results.isEmpty()) { + throw new AssertionFailedError(getFormattedErrorMessage()); + } + } + + private String getFormattedErrorMessage() { + StringBuilder message = new StringBuilder(); + message + .append(results.size()) + .append(" assertion(s) failed:"); + + for (Throwable t : results) { + message.append("\n"); + message.append("----------------------------------------\n"); + message.append(t.getMessage()); + } + + return message.toString(); + } +} diff --git a/playwright/src/test/java/com/microsoft/playwright/TestSoftAPIResponseAssertions.java b/playwright/src/test/java/com/microsoft/playwright/TestSoftAPIResponseAssertions.java new file mode 100644 index 000000000..7677ddef3 --- /dev/null +++ b/playwright/src/test/java/com/microsoft/playwright/TestSoftAPIResponseAssertions.java @@ -0,0 +1,46 @@ +package com.microsoft.playwright; + +import com.microsoft.playwright.assertions.APIResponseAssertions; +import com.microsoft.playwright.impl.APIResponseAssertionsImpl; +import com.microsoft.playwright.impl.APIResponseAssertionsImplProxy; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.ArrayList; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.verify; + +// The only thing we want to verify in these tests is that the correct method was called +@ExtendWith(MockitoExtension.class) +public class TestSoftAPIResponseAssertions { + @Mock + private APIResponseAssertionsImpl apiResponseAssertionsMock; + APIResponseAssertionsImplProxy proxy; + + @BeforeEach + void beforeEach() { + proxy = new APIResponseAssertionsImplProxy(new ArrayList<>(), apiResponseAssertionsMock); + } + + @Test + void proxyImplementsAPIResponseAssertions() { + assertTrue(APIResponseAssertions.class.isAssignableFrom(proxy.getClass())); + } + + @Test + void not() { + proxy.not(); + verify(apiResponseAssertionsMock).not(); + } + + @Test + void isOK() { + assertDoesNotThrow(() -> proxy.isOK()); + verify(apiResponseAssertionsMock).isOK(); + } +} diff --git a/playwright/src/test/java/com/microsoft/playwright/TestSoftAssertions.java b/playwright/src/test/java/com/microsoft/playwright/TestSoftAssertions.java new file mode 100644 index 000000000..047319cc3 --- /dev/null +++ b/playwright/src/test/java/com/microsoft/playwright/TestSoftAssertions.java @@ -0,0 +1,49 @@ +package com.microsoft.playwright; + +import com.microsoft.playwright.assertions.LocatorAssertions; +import com.microsoft.playwright.assertions.SoftAssertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.opentest4j.AssertionFailedError; + +import static com.microsoft.playwright.Utils.assertFailureCount; +import static org.junit.jupiter.api.Assertions.*; + +public class TestSoftAssertions extends TestBase { + private SoftAssertions softly; + + @BeforeEach + void beforeEach() { + softly = SoftAssertions.create(); + } + + @Test + void canMakeMultipleAssertionsWithoutFailingImmediately() { + page.setContent("
Text content
"); + Locator locator = page.locator(".foo"); + assertDoesNotThrow(() -> softly.assertThat(locator).hasText("Text content")); + assertDoesNotThrow(() -> softly.assertThat(locator).hasClass("foo bar")); + assertDoesNotThrow(() -> softly.assertThat(locator).hasId("node")); + softly.assertAll(); + assertFailureCount(softly, 0); + } + + @Test + void failureMessageIncludesMessagesFromAllAssertions() { + page.setContent("
Text content
"); + Locator locator = page.locator(".foo"); + assertDoesNotThrow(() -> softly.assertThat(locator).hasText("some text", new LocatorAssertions.HasTextOptions().setTimeout(1000))); + assertDoesNotThrow(() -> softly.assertThat(locator).hasClass("abc", new LocatorAssertions.HasClassOptions().setTimeout(1000))); + assertDoesNotThrow(() -> softly.assertThat(locator).hasId("foo", new LocatorAssertions.HasIdOptions().setTimeout(1000))); + AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> softly.assertAll()); + + assertTrue(e.getMessage().contains("3 assertion(s) failed")); + assertTrue(e.getMessage().contains("Locator expected to have text: some text")); + assertTrue(e.getMessage().contains("Received: Text content")); + assertTrue(e.getMessage().contains("Locator expected to have class: abc")); + assertTrue(e.getMessage().contains("Received: foo bar")); + assertTrue(e.getMessage().contains("Locator expected to have ID: foo")); + assertTrue(e.getMessage().contains("Received: node")); + assertFailureCount(softly, 3); + } +} diff --git a/playwright/src/test/java/com/microsoft/playwright/TestSoftLocatorAssertions.java b/playwright/src/test/java/com/microsoft/playwright/TestSoftLocatorAssertions.java new file mode 100644 index 000000000..6ed16fd91 --- /dev/null +++ b/playwright/src/test/java/com/microsoft/playwright/TestSoftLocatorAssertions.java @@ -0,0 +1,248 @@ +package com.microsoft.playwright; + +import com.microsoft.playwright.assertions.LocatorAssertions; +import com.microsoft.playwright.impl.LocatorAssertionsImpl; +import com.microsoft.playwright.impl.LocatorAssertionsImplProxy; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.ArrayList; +import java.util.regex.Pattern; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.verify; + +// The only thing we want to verify in these tests is that the correct method was called +@ExtendWith(MockitoExtension.class) +public class TestSoftLocatorAssertions { + @Mock + private LocatorAssertionsImpl locatorAssertionsMock; + private final static Pattern pattern = Pattern.compile(""); + private final static Pattern[] patternArray = new Pattern[]{}; + private final static String[] stringArray = new String[]{}; + LocatorAssertionsImplProxy proxy; + + @BeforeEach + void beforeEach() { + proxy = new LocatorAssertionsImplProxy(new ArrayList<>(), locatorAssertionsMock); + } + + @Test + void proxyImplementsLocatorAssertions() { + assertTrue(LocatorAssertions.class.isAssignableFrom(proxy.getClass())); + } + + @Test + void not() { + proxy.not(); + verify(locatorAssertionsMock).not(); + } + + @Test + void isAttached() { + assertDoesNotThrow(() -> proxy.isAttached(null)); + verify(locatorAssertionsMock).isAttached(null); + } + + @Test + void isChecked() { + assertDoesNotThrow(() -> proxy.isChecked(null)); + verify(locatorAssertionsMock).isChecked(null); + } + + @Test + void isDisabled() { + assertDoesNotThrow(() -> proxy.isDisabled(null)); + verify(locatorAssertionsMock).isDisabled(null); + } + + @Test + void isEditable() { + assertDoesNotThrow(() -> proxy.isEditable(null)); + verify(locatorAssertionsMock).isEditable(null); + } + + @Test + void isEmpty() { + assertDoesNotThrow(() -> proxy.isEmpty(null)); + verify(locatorAssertionsMock).isEmpty(null); + } + + @Test + void isEnabled() { + assertDoesNotThrow(() -> proxy.isEnabled(null)); + verify(locatorAssertionsMock).isEnabled(null); + } + + @Test + void isFocused() { + assertDoesNotThrow(() -> proxy.isFocused(null)); + verify(locatorAssertionsMock).isFocused(null); + } + + @Test + void isHidden() { + assertDoesNotThrow(() -> proxy.isHidden(null)); + verify(locatorAssertionsMock).isHidden(null); + } + + @Test + void isInViewPort() { + assertDoesNotThrow(() -> proxy.isInViewport(null)); + verify(locatorAssertionsMock).isInViewport(null); + } + + @Test + void isVisible() { + assertDoesNotThrow(() -> proxy.isVisible(null)); + verify(locatorAssertionsMock).isVisible(null); + } + + @Test + void containsTextString() { + assertDoesNotThrow(() -> proxy.containsText("", null)); + verify(locatorAssertionsMock).containsText("", null); + } + + @Test + void containsTextPattern() { + assertDoesNotThrow(() -> proxy.containsText(pattern, null)); + verify(locatorAssertionsMock).containsText(pattern, null); + } + + @Test + void containsTextStringArray() { + assertDoesNotThrow(() -> proxy.containsText(stringArray, null)); + verify(locatorAssertionsMock).containsText(stringArray, null); + } + + @Test + void containsTextPatternArray() { + assertDoesNotThrow(() -> proxy.containsText(patternArray, null)); + verify(locatorAssertionsMock).containsText(patternArray, null); + } + + @Test + void hasAttributeStringValue() { + assertDoesNotThrow(() -> proxy.hasAttribute("", "", null)); + verify(locatorAssertionsMock).hasAttribute("", "", null); + } + + @Test + void hasAttributePatternValue() { + assertDoesNotThrow(() -> proxy.hasAttribute("", pattern, null)); + verify(locatorAssertionsMock).hasAttribute("", pattern, null); + } + + @Test + void hasClassString() { + assertDoesNotThrow(() -> proxy.hasClass("", null)); + verify(locatorAssertionsMock).hasClass("", null); + } + + @Test + void hasClassPattern() { + assertDoesNotThrow(() -> proxy.hasClass(pattern, null)); + verify(locatorAssertionsMock).hasClass(pattern, null); + } + + @Test + void hasClassStringArray() { + assertDoesNotThrow(() -> proxy.hasClass(stringArray, null)); + verify(locatorAssertionsMock).hasClass(stringArray, null); + } + + @Test + void hasClassPatternArray() { + assertDoesNotThrow(() -> proxy.hasClass(patternArray, null)); + verify(locatorAssertionsMock).hasClass(patternArray, null); + } + + @Test + void hasCount() { + assertDoesNotThrow(() -> proxy.hasCount(0, null)); + verify(locatorAssertionsMock).hasCount(0, null); + } + + @Test + void hasCSSString() { + assertDoesNotThrow(() -> proxy.hasCSS("", "", null)); + verify(locatorAssertionsMock).hasCSS("", "", null); + } + + @Test + void hasCSSPattern() { + assertDoesNotThrow(() -> proxy.hasCSS("", pattern, null)); + verify(locatorAssertionsMock).hasCSS("", pattern, null); + } + + @Test + void hasIdString() { + assertDoesNotThrow(() -> proxy.hasId("", null)); + verify(locatorAssertionsMock).hasId("", null); + } + + @Test + void hasIdPattern() { + assertDoesNotThrow(() -> proxy.hasId(pattern, null)); + verify(locatorAssertionsMock).hasId(pattern, null); + } + + @Test + void hasJSProperty() { + assertDoesNotThrow(() -> proxy.hasJSProperty("", null, null)); + verify(locatorAssertionsMock).hasJSProperty("", null, null); + } + + @Test + void hasTextString() { + assertDoesNotThrow(() -> proxy.hasText("", null)); + verify(locatorAssertionsMock).hasText("", null); + } + + @Test + void hasTextPattern() { + assertDoesNotThrow(() -> proxy.hasText(pattern, null)); + verify(locatorAssertionsMock).hasText(pattern, null); + } + + @Test + void hasTextStringArray() { + assertDoesNotThrow(() -> proxy.hasText(stringArray, null)); + verify(locatorAssertionsMock).hasText(stringArray, null); + } + + @Test + void hasTextPatternArray() { + assertDoesNotThrow(() -> proxy.hasText(patternArray, null)); + verify(locatorAssertionsMock).hasText(patternArray, null); + } + + @Test + void hasValueString() { + assertDoesNotThrow(() -> proxy.hasValue("", null)); + verify(locatorAssertionsMock).hasValue("", null); + } + + @Test + void hasValuePattern() { + assertDoesNotThrow(() -> proxy.hasValue(pattern, null)); + verify(locatorAssertionsMock).hasValue(pattern, null); + } + + @Test + void hasValuesStringArray() { + assertDoesNotThrow(() -> proxy.hasValues(stringArray, null)); + verify(locatorAssertionsMock).hasValues(stringArray, null); + } + + @Test + void hasValuesPatternArray() { + assertDoesNotThrow(() -> proxy.hasValues(patternArray, null)); + verify(locatorAssertionsMock).hasValues(patternArray, null); + } +} diff --git a/playwright/src/test/java/com/microsoft/playwright/TestSoftPageAssertions.java b/playwright/src/test/java/com/microsoft/playwright/TestSoftPageAssertions.java new file mode 100644 index 000000000..d014c59d9 --- /dev/null +++ b/playwright/src/test/java/com/microsoft/playwright/TestSoftPageAssertions.java @@ -0,0 +1,66 @@ +package com.microsoft.playwright; + +import com.microsoft.playwright.assertions.PageAssertions; +import com.microsoft.playwright.impl.PageAssertionsImpl; +import com.microsoft.playwright.impl.PageAssertionsImplProxy; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.ArrayList; +import java.util.regex.Pattern; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.verify; + +// The only thing we want to verify in these tests is that the correct method was called +@ExtendWith(MockitoExtension.class) +public class TestSoftPageAssertions { + @Mock + private PageAssertionsImpl pageAssertionsMock; + PageAssertionsImplProxy proxy; + private final static Pattern pattern = Pattern.compile(""); + + @BeforeEach + void beforeEach() { + proxy = new PageAssertionsImplProxy(new ArrayList<>(), pageAssertionsMock); + } + + @Test + void proxyImplementsPageAssertions() { + assertTrue(PageAssertions.class.isAssignableFrom(proxy.getClass())); + } + + @Test + void not() { + proxy.not(); + verify(pageAssertionsMock).not(); + } + + @Test + void hasTitleString() { + assertDoesNotThrow(() -> proxy.hasTitle("", null)); + verify(pageAssertionsMock).hasTitle("", null); + } + + @Test + void hasTitlePattern() { + assertDoesNotThrow(() -> proxy.hasTitle(pattern, null)); + verify(pageAssertionsMock).hasTitle(pattern, null); + } + + @Test + void hasURLString() { + assertDoesNotThrow(() -> proxy.hasURL("", null)); + verify(pageAssertionsMock).hasURL("", null); + } + + @Test + void hasURLPattern() { + assertDoesNotThrow(() -> proxy.hasURL(pattern, null)); + verify(pageAssertionsMock).hasURL(pattern, null); + } +} diff --git a/playwright/src/test/java/com/microsoft/playwright/Utils.java b/playwright/src/test/java/com/microsoft/playwright/Utils.java index dff6bab20..7e3c3ca19 100644 --- a/playwright/src/test/java/com/microsoft/playwright/Utils.java +++ b/playwright/src/test/java/com/microsoft/playwright/Utils.java @@ -19,8 +19,10 @@ import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonParser; +import com.microsoft.playwright.assertions.SoftAssertions; import java.io.*; +import java.lang.reflect.Field; import java.net.ServerSocket; import java.nio.file.Files; import java.nio.file.Path; @@ -214,4 +216,16 @@ static String generateDifferentOriginHostname(final Server server){ static String generateDifferentOriginPort(final Server server){ return server.PREFIX.replace(String.valueOf(server.PORT), String.valueOf(server.PORT+1)); } + + static void assertFailureCount(SoftAssertions softAssertions, int expectedFailureCount) { + try { + Class clazz = softAssertions.getClass(); + Field resultsField = clazz.getDeclaredField("results"); + resultsField.setAccessible(true); + List results = (List) resultsField.get(softAssertions); + assertEquals(expectedFailureCount, results.size()); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } } diff --git a/pom.xml b/pom.xml index 38e62faaa..0542f5905 100644 --- a/pom.xml +++ b/pom.xml @@ -49,6 +49,7 @@ UTF-8 1.5.1 1.2.0 + 4.11.0 @@ -79,12 +80,24 @@ ${junit.version} test + + org.junit.jupiter + junit-jupiter-params + ${junit.version} + test + org.java-websocket Java-WebSocket ${websocket.version} test + + org.mockito + mockito-junit-jupiter + ${mockito.version} + test + diff --git a/scripts/CLI_VERSION b/scripts/CLI_VERSION index 3d0258087..faaf9e47d 100644 --- a/scripts/CLI_VERSION +++ b/scripts/CLI_VERSION @@ -1 +1 @@ -1.37.0-beta-1691701681000 +1.38.0-alpha-1692320133000 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 caf601f5b..2951a82ac 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 @@ -688,6 +688,13 @@ void writeTo(List output, String offset) { output.add(""); return; } + if ("SoftAssertions.create".equals(jsonPath)) { + writeJavadoc(params, output, offset); + output.add(offset + "static SoftAssertions create() {"); + output.add(offset + " return new SoftAssertionsImpl();"); + output.add(offset + "}"); + return; + } int numOverloads = 1; for (int i = 0; i < params.size(); i++) { if (params.get(i).type.isTypeUnion()) { @@ -989,6 +996,11 @@ void writeTo(List output, String offset) { output.add("import com.microsoft.playwright.impl.LocatorAssertionsImpl;"); output.add("import com.microsoft.playwright.impl.PageAssertionsImpl;"); } + if ("SoftAssertions".equals(jsonName)) { + output.add("import com.microsoft.playwright.APIResponse;"); + output.add("import com.microsoft.playwright.Locator;"); + output.add("import com.microsoft.playwright.Page;"); + } output.add(""); List superInterfaces = new ArrayList<>(); From 9d0ad9dd38f795fa29fb5622bd45221327c0245c Mon Sep 17 00:00:00 2001 From: Umair Chagani Date: Wed, 23 Aug 2023 08:01:54 -0400 Subject: [PATCH 2/8] feat(soft-assertions): Cleanup access modifiers --- .../impl/APIResponseAssertionsImplProxy.java | 2 +- .../impl/LocatorAssertionsImplProxy.java | 4 ++-- .../impl/PageAssertionsImplProxy.java | 2 +- .../TestSoftAPIResponseAssertions.java | 5 +++-- .../playwright/TestSoftAssertions.java | 16 +++++++++++++- .../playwright/TestSoftLocatorAssertions.java | 8 +++++-- .../playwright/TestSoftPageAssertions.java | 5 +++-- .../java/com/microsoft/playwright/Utils.java | 22 +++++++++---------- 8 files changed, 41 insertions(+), 23 deletions(-) diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/APIResponseAssertionsImplProxy.java b/playwright/src/main/java/com/microsoft/playwright/impl/APIResponseAssertionsImplProxy.java index 049e6e009..7e35212c3 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/APIResponseAssertionsImplProxy.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/APIResponseAssertionsImplProxy.java @@ -28,7 +28,7 @@ public class APIResponseAssertionsImplProxy extends SoftAssertionsBase implement this(results, new APIResponseAssertionsImpl(response)); } - public APIResponseAssertionsImplProxy(List results, APIResponseAssertionsImpl apiResponseAssertionsImpl) { + private APIResponseAssertionsImplProxy(List results, APIResponseAssertionsImpl apiResponseAssertionsImpl) { super(results); this.apiResponseAssertionsImpl = apiResponseAssertionsImpl; } diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/LocatorAssertionsImplProxy.java b/playwright/src/main/java/com/microsoft/playwright/impl/LocatorAssertionsImplProxy.java index 4b8a18e54..422510a94 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/LocatorAssertionsImplProxy.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/LocatorAssertionsImplProxy.java @@ -9,11 +9,11 @@ public class LocatorAssertionsImplProxy extends SoftAssertionsBase implements LocatorAssertions { private final LocatorAssertionsImpl locatorAssertionsImpl; - public LocatorAssertionsImplProxy(Locator locator, List results) { + LocatorAssertionsImplProxy(Locator locator, List results) { this(results, new LocatorAssertionsImpl(locator)); } - public LocatorAssertionsImplProxy(List results, LocatorAssertionsImpl locatorAssertionsImpl) { + private LocatorAssertionsImplProxy(List results, LocatorAssertionsImpl locatorAssertionsImpl) { super(results); this.locatorAssertionsImpl = locatorAssertionsImpl; } diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/PageAssertionsImplProxy.java b/playwright/src/main/java/com/microsoft/playwright/impl/PageAssertionsImplProxy.java index 60eaebf0c..51e8a6a64 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/PageAssertionsImplProxy.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/PageAssertionsImplProxy.java @@ -29,7 +29,7 @@ public class PageAssertionsImplProxy extends SoftAssertionsBase implements PageA this(results, new PageAssertionsImpl(page)); } - public PageAssertionsImplProxy(List results, PageAssertionsImpl pageAssertionsImpl) { + private PageAssertionsImplProxy(List results, PageAssertionsImpl pageAssertionsImpl) { super(results); this.pageAssertionsImpl = pageAssertionsImpl; } diff --git a/playwright/src/test/java/com/microsoft/playwright/TestSoftAPIResponseAssertions.java b/playwright/src/test/java/com/microsoft/playwright/TestSoftAPIResponseAssertions.java index 7677ddef3..b790d4047 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestSoftAPIResponseAssertions.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestSoftAPIResponseAssertions.java @@ -11,6 +11,7 @@ import java.util.ArrayList; +import static com.microsoft.playwright.Utils.createProxy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.verify; @@ -20,11 +21,11 @@ public class TestSoftAPIResponseAssertions { @Mock private APIResponseAssertionsImpl apiResponseAssertionsMock; - APIResponseAssertionsImplProxy proxy; + private APIResponseAssertionsImplProxy proxy; @BeforeEach void beforeEach() { - proxy = new APIResponseAssertionsImplProxy(new ArrayList<>(), apiResponseAssertionsMock); + proxy = createProxy(APIResponseAssertionsImplProxy.class, apiResponseAssertionsMock); } @Test diff --git a/playwright/src/test/java/com/microsoft/playwright/TestSoftAssertions.java b/playwright/src/test/java/com/microsoft/playwright/TestSoftAssertions.java index 047319cc3..8dc64c923 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestSoftAssertions.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestSoftAssertions.java @@ -6,7 +6,9 @@ import org.junit.jupiter.api.Test; import org.opentest4j.AssertionFailedError; -import static com.microsoft.playwright.Utils.assertFailureCount; +import java.lang.reflect.Field; +import java.util.List; + import static org.junit.jupiter.api.Assertions.*; public class TestSoftAssertions extends TestBase { @@ -46,4 +48,16 @@ void failureMessageIncludesMessagesFromAllAssertions() { assertTrue(e.getMessage().contains("Received: node")); assertFailureCount(softly, 3); } + + private static void assertFailureCount(SoftAssertions softAssertions, int expectedFailureCount) { + try { + Class clazz = softAssertions.getClass(); + Field resultsField = clazz.getDeclaredField("results"); + resultsField.setAccessible(true); + List results = (List) resultsField.get(softAssertions); + assertEquals(expectedFailureCount, results.size()); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } } diff --git a/playwright/src/test/java/com/microsoft/playwright/TestSoftLocatorAssertions.java b/playwright/src/test/java/com/microsoft/playwright/TestSoftLocatorAssertions.java index 6ed16fd91..ea39e2295 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestSoftLocatorAssertions.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestSoftLocatorAssertions.java @@ -9,9 +9,13 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; +import java.util.List; import java.util.regex.Pattern; +import static com.microsoft.playwright.Utils.createProxy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.verify; @@ -24,11 +28,11 @@ public class TestSoftLocatorAssertions { private final static Pattern pattern = Pattern.compile(""); private final static Pattern[] patternArray = new Pattern[]{}; private final static String[] stringArray = new String[]{}; - LocatorAssertionsImplProxy proxy; + private LocatorAssertionsImplProxy proxy; @BeforeEach void beforeEach() { - proxy = new LocatorAssertionsImplProxy(new ArrayList<>(), locatorAssertionsMock); + proxy = createProxy(LocatorAssertionsImplProxy.class, locatorAssertionsMock); } @Test diff --git a/playwright/src/test/java/com/microsoft/playwright/TestSoftPageAssertions.java b/playwright/src/test/java/com/microsoft/playwright/TestSoftPageAssertions.java index d014c59d9..082dae7ae 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestSoftPageAssertions.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestSoftPageAssertions.java @@ -12,6 +12,7 @@ import java.util.ArrayList; import java.util.regex.Pattern; +import static com.microsoft.playwright.Utils.createProxy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.verify; @@ -21,12 +22,12 @@ public class TestSoftPageAssertions { @Mock private PageAssertionsImpl pageAssertionsMock; - PageAssertionsImplProxy proxy; + private PageAssertionsImplProxy proxy; private final static Pattern pattern = Pattern.compile(""); @BeforeEach void beforeEach() { - proxy = new PageAssertionsImplProxy(new ArrayList<>(), pageAssertionsMock); + proxy = createProxy(PageAssertionsImplProxy.class, pageAssertionsMock); } @Test diff --git a/playwright/src/test/java/com/microsoft/playwright/Utils.java b/playwright/src/test/java/com/microsoft/playwright/Utils.java index 7e3c3ca19..09ef94dde 100644 --- a/playwright/src/test/java/com/microsoft/playwright/Utils.java +++ b/playwright/src/test/java/com/microsoft/playwright/Utils.java @@ -22,19 +22,19 @@ import com.microsoft.playwright.assertions.SoftAssertions; import java.io.*; +import java.lang.reflect.Constructor; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; import java.net.ServerSocket; import java.nio.file.Files; import java.nio.file.Path; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mockingDetails; class Utils { private static final AtomicInteger nextUnusedPort = new AtomicInteger(9000); @@ -217,15 +217,13 @@ static String generateDifferentOriginPort(final Server server){ return server.PREFIX.replace(String.valueOf(server.PORT), String.valueOf(server.PORT+1)); } - static void assertFailureCount(SoftAssertions softAssertions, int expectedFailureCount) { + static T createProxy(Class proxyToCreate, Object underlyingObject) { try { - Class clazz = softAssertions.getClass(); - Field resultsField = clazz.getDeclaredField("results"); - resultsField.setAccessible(true); - List results = (List) resultsField.get(softAssertions); - assertEquals(expectedFailureCount, results.size()); - } catch (NoSuchFieldException | IllegalAccessException e) { - throw new RuntimeException(e); + Constructor constructor = proxyToCreate.getDeclaredConstructor(List.class, mockingDetails(underlyingObject).getMockCreationSettings().getTypeToMock()); + constructor.setAccessible(true); + return (T) proxyToCreate.cast(constructor.newInstance(new ArrayList<>(), underlyingObject)); + } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) { + throw new RuntimeException("Unable to create proxy", e); } } } From 32470031875486b478ad46f22dbebc2921e2ea19 Mon Sep 17 00:00:00 2001 From: Umair Chagani Date: Wed, 23 Aug 2023 08:40:29 -0400 Subject: [PATCH 3/8] feat(soft-assertions): Cleanup --- .../com/microsoft/playwright/TestSoftAssertions.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/playwright/src/test/java/com/microsoft/playwright/TestSoftAssertions.java b/playwright/src/test/java/com/microsoft/playwright/TestSoftAssertions.java index 8dc64c923..31cd8b276 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestSoftAssertions.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestSoftAssertions.java @@ -27,7 +27,7 @@ void canMakeMultipleAssertionsWithoutFailingImmediately() { assertDoesNotThrow(() -> softly.assertThat(locator).hasClass("foo bar")); assertDoesNotThrow(() -> softly.assertThat(locator).hasId("node")); softly.assertAll(); - assertFailureCount(softly, 0); + assertFailureCount(0); } @Test @@ -46,15 +46,15 @@ void failureMessageIncludesMessagesFromAllAssertions() { assertTrue(e.getMessage().contains("Received: foo bar")); assertTrue(e.getMessage().contains("Locator expected to have ID: foo")); assertTrue(e.getMessage().contains("Received: node")); - assertFailureCount(softly, 3); + assertFailureCount(3); } - private static void assertFailureCount(SoftAssertions softAssertions, int expectedFailureCount) { + private void assertFailureCount(int expectedFailureCount) { try { - Class clazz = softAssertions.getClass(); + Class clazz = softly.getClass(); Field resultsField = clazz.getDeclaredField("results"); resultsField.setAccessible(true); - List results = (List) resultsField.get(softAssertions); + List results = (List) resultsField.get(softly); assertEquals(expectedFailureCount, results.size()); } catch (NoSuchFieldException | IllegalAccessException e) { throw new RuntimeException(e); From 7462b6f5ae1e1f13a65d10a734ebd69688cbe8f0 Mon Sep 17 00:00:00 2001 From: Umair Chagani Date: Wed, 23 Aug 2023 08:42:53 -0400 Subject: [PATCH 4/8] feat(soft-assertions): remove unnecessary dependency --- pom.xml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/pom.xml b/pom.xml index 0542f5905..a16520bbc 100644 --- a/pom.xml +++ b/pom.xml @@ -80,12 +80,6 @@ ${junit.version} test - - org.junit.jupiter - junit-jupiter-params - ${junit.version} - test - org.java-websocket Java-WebSocket From 3ca1cd7f81164aca2e581c22abf2fa3c008d1241 Mon Sep 17 00:00:00 2001 From: Umair Chagani Date: Thu, 24 Aug 2023 08:23:34 -0400 Subject: [PATCH 5/8] feat(soft-assertions): update code to reflect latest changes in branch and PR review comments --- .../playwright/assertions/SoftAssertions.java | 114 ------------------ .../TestSoftAPIResponseAssertions.java | 2 - .../playwright/TestSoftAssertions.java | 17 --- .../playwright/TestSoftLocatorAssertions.java | 4 - .../playwright/TestSoftPageAssertions.java | 1 - .../java/com/microsoft/playwright/Utils.java | 2 - .../playwright/tools/ApiGenerator.java | 7 +- 7 files changed, 1 insertion(+), 146 deletions(-) delete mode 100644 playwright/src/main/java/com/microsoft/playwright/assertions/SoftAssertions.java diff --git a/playwright/src/main/java/com/microsoft/playwright/assertions/SoftAssertions.java b/playwright/src/main/java/com/microsoft/playwright/assertions/SoftAssertions.java deleted file mode 100644 index 618cc7a0b..000000000 --- a/playwright/src/main/java/com/microsoft/playwright/assertions/SoftAssertions.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * 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.assertions; - -import com.microsoft.playwright.impl.SoftAssertionsImpl; -import com.microsoft.playwright.APIResponse; -import com.microsoft.playwright.Locator; -import com.microsoft.playwright.Page; - -/** - * The {@code SoftAssertions} class provides assertion methods that can be used to make multiple assertions without failing - * the test immediately. - *
{@code
- * ...
- * import com.microsoft.playwright.assertions.SoftAssertions;
- *
- * public class TestPage {
- *   ...
- *   @Test
- *   void hasUrlTextPass() {
- *     SoftAssertions softly = SoftAssertions.create();
- *     page.getByText("Sign in").click();
- *     softly.assertThat(page).hasURL(Pattern.compile(".*\/login"));
- *     softly.assertAll();
- *   }
- * }
- * }
- */ -public interface SoftAssertions { - /** - * Creates a {@code SoftAssertions} object. - * - *

**Usage** - *

{@code
-   * SoftAssertions softly = SoftAssertions.create();
-   * }
- * - * @since v1.38 - */ - static SoftAssertions create() { - return new SoftAssertionsImpl(); - } - /** - * Creates a {@code LocatorAssertions} object for the given {@code Locator}. - * - *

**Usage** - *

{@code
-   * SoftAssertions softly = SoftAssertions.create();
-   * ...
-   * softly.assertThat(locator).isVisible();
-   * }
- * - * @param locator {@code Locator} object to use for assertions. - * @since v1.38 - */ - LocatorAssertions assertThat(Locator locator); - /** - * Creates a {@code PageAssertions} object for the given {@code Page}. - * - *

**Usage** - *

{@code
-   * SoftAssertions softly = SoftAssertions.create();
-   * ...
-   * softly.assertThat(page).hasTitle("News");
-   * }
- * - * @param page {@code Page} object to use for assertions. - * @since v1.38 - */ - PageAssertions assertThat(Page page); - /** - * Creates a {@code APIResponseAssertions} object for the given {@code APIResponse}. - * - *

**Usage** - *

{@code
-   * SoftAssertions softly = SoftAssertions.create();
-   * ...
-   * softly.assertThat(response).isOK();
-   * }
- * - * @param response {@code APIResponse} object to use for assertions. - * @since v1.38 - */ - APIResponseAssertions assertThat(APIResponse response); - /** - * Runs all the assertions have been executed for this {@code SoftAssertions} object. If any assertions fail, this method - * throws an AssertionFailedError with the details of all the failed assertions. - * - *

**Usage** - *

{@code
-   * SoftAssertions softly = SoftAssertions.create();
-   * ...
-   * softly.assertAll();
-   * }
- * - * @since v1.38 - */ - void assertAll(); -} - diff --git a/playwright/src/test/java/com/microsoft/playwright/TestSoftAPIResponseAssertions.java b/playwright/src/test/java/com/microsoft/playwright/TestSoftAPIResponseAssertions.java index b790d4047..c1dc6ebf6 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestSoftAPIResponseAssertions.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestSoftAPIResponseAssertions.java @@ -9,8 +9,6 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import java.util.ArrayList; - import static com.microsoft.playwright.Utils.createProxy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertTrue; diff --git a/playwright/src/test/java/com/microsoft/playwright/TestSoftAssertions.java b/playwright/src/test/java/com/microsoft/playwright/TestSoftAssertions.java index 31cd8b276..d265c1ff2 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestSoftAssertions.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestSoftAssertions.java @@ -6,9 +6,6 @@ import org.junit.jupiter.api.Test; import org.opentest4j.AssertionFailedError; -import java.lang.reflect.Field; -import java.util.List; - import static org.junit.jupiter.api.Assertions.*; public class TestSoftAssertions extends TestBase { @@ -27,7 +24,6 @@ void canMakeMultipleAssertionsWithoutFailingImmediately() { assertDoesNotThrow(() -> softly.assertThat(locator).hasClass("foo bar")); assertDoesNotThrow(() -> softly.assertThat(locator).hasId("node")); softly.assertAll(); - assertFailureCount(0); } @Test @@ -46,18 +42,5 @@ void failureMessageIncludesMessagesFromAllAssertions() { assertTrue(e.getMessage().contains("Received: foo bar")); assertTrue(e.getMessage().contains("Locator expected to have ID: foo")); assertTrue(e.getMessage().contains("Received: node")); - assertFailureCount(3); - } - - private void assertFailureCount(int expectedFailureCount) { - try { - Class clazz = softly.getClass(); - Field resultsField = clazz.getDeclaredField("results"); - resultsField.setAccessible(true); - List results = (List) resultsField.get(softly); - assertEquals(expectedFailureCount, results.size()); - } catch (NoSuchFieldException | IllegalAccessException e) { - throw new RuntimeException(e); - } } } diff --git a/playwright/src/test/java/com/microsoft/playwright/TestSoftLocatorAssertions.java b/playwright/src/test/java/com/microsoft/playwright/TestSoftLocatorAssertions.java index ea39e2295..1a1e4c99d 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestSoftLocatorAssertions.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestSoftLocatorAssertions.java @@ -9,10 +9,6 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.List; import java.util.regex.Pattern; import static com.microsoft.playwright.Utils.createProxy; diff --git a/playwright/src/test/java/com/microsoft/playwright/TestSoftPageAssertions.java b/playwright/src/test/java/com/microsoft/playwright/TestSoftPageAssertions.java index 082dae7ae..63696ad26 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestSoftPageAssertions.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestSoftPageAssertions.java @@ -9,7 +9,6 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import java.util.ArrayList; import java.util.regex.Pattern; import static com.microsoft.playwright.Utils.createProxy; diff --git a/playwright/src/test/java/com/microsoft/playwright/Utils.java b/playwright/src/test/java/com/microsoft/playwright/Utils.java index 09ef94dde..e4e9a21dc 100644 --- a/playwright/src/test/java/com/microsoft/playwright/Utils.java +++ b/playwright/src/test/java/com/microsoft/playwright/Utils.java @@ -19,11 +19,9 @@ import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonParser; -import com.microsoft.playwright.assertions.SoftAssertions; import java.io.*; import java.lang.reflect.Constructor; -import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.net.ServerSocket; import java.nio.file.Files; 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 fa1db0919..2951a82ac 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 @@ -1168,18 +1168,13 @@ public class ApiGenerator { File assertionsDir = new File(cwd,"playwright/src/main/java/com/microsoft/playwright/assertions"); System.out.println("Writing assertion files to: " + dir.getCanonicalPath()); - generate(api, assertionsDir, "com.microsoft.playwright.assertions", isAssertion().and(isSoftAssertion().negate())); + generate(api, assertionsDir, "com.microsoft.playwright.assertions", isAssertion()); } private static Predicate isAssertion() { return className -> className.toLowerCase().contains("assert"); } - // TODO: Remove this predicate once SoftAssertions are implemented. - private static Predicate isSoftAssertion() { - return className -> className.contains("SoftAssertions"); - } - private void generate(JsonArray api, File dir, String packageName, Predicate classFilter) throws IOException { Map topLevelTypes = new HashMap<>(); for (JsonElement entry: api) { From f69903cbabe90af78d5feaff3ae3391b351440cb Mon Sep 17 00:00:00 2001 From: Umair Chagani Date: Thu, 24 Aug 2023 08:24:14 -0400 Subject: [PATCH 6/8] feat(soft-assertions): Add back generated SoftAssertions --- .../playwright/assertions/SoftAssertions.java | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 playwright/src/main/java/com/microsoft/playwright/assertions/SoftAssertions.java diff --git a/playwright/src/main/java/com/microsoft/playwright/assertions/SoftAssertions.java b/playwright/src/main/java/com/microsoft/playwright/assertions/SoftAssertions.java new file mode 100644 index 000000000..618cc7a0b --- /dev/null +++ b/playwright/src/main/java/com/microsoft/playwright/assertions/SoftAssertions.java @@ -0,0 +1,114 @@ +/* + * 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.assertions; + +import com.microsoft.playwright.impl.SoftAssertionsImpl; +import com.microsoft.playwright.APIResponse; +import com.microsoft.playwright.Locator; +import com.microsoft.playwright.Page; + +/** + * The {@code SoftAssertions} class provides assertion methods that can be used to make multiple assertions without failing + * the test immediately. + *
{@code
+ * ...
+ * import com.microsoft.playwright.assertions.SoftAssertions;
+ *
+ * public class TestPage {
+ *   ...
+ *   @Test
+ *   void hasUrlTextPass() {
+ *     SoftAssertions softly = SoftAssertions.create();
+ *     page.getByText("Sign in").click();
+ *     softly.assertThat(page).hasURL(Pattern.compile(".*\/login"));
+ *     softly.assertAll();
+ *   }
+ * }
+ * }
+ */ +public interface SoftAssertions { + /** + * Creates a {@code SoftAssertions} object. + * + *

**Usage** + *

{@code
+   * SoftAssertions softly = SoftAssertions.create();
+   * }
+ * + * @since v1.38 + */ + static SoftAssertions create() { + return new SoftAssertionsImpl(); + } + /** + * Creates a {@code LocatorAssertions} object for the given {@code Locator}. + * + *

**Usage** + *

{@code
+   * SoftAssertions softly = SoftAssertions.create();
+   * ...
+   * softly.assertThat(locator).isVisible();
+   * }
+ * + * @param locator {@code Locator} object to use for assertions. + * @since v1.38 + */ + LocatorAssertions assertThat(Locator locator); + /** + * Creates a {@code PageAssertions} object for the given {@code Page}. + * + *

**Usage** + *

{@code
+   * SoftAssertions softly = SoftAssertions.create();
+   * ...
+   * softly.assertThat(page).hasTitle("News");
+   * }
+ * + * @param page {@code Page} object to use for assertions. + * @since v1.38 + */ + PageAssertions assertThat(Page page); + /** + * Creates a {@code APIResponseAssertions} object for the given {@code APIResponse}. + * + *

**Usage** + *

{@code
+   * SoftAssertions softly = SoftAssertions.create();
+   * ...
+   * softly.assertThat(response).isOK();
+   * }
+ * + * @param response {@code APIResponse} object to use for assertions. + * @since v1.38 + */ + APIResponseAssertions assertThat(APIResponse response); + /** + * Runs all the assertions have been executed for this {@code SoftAssertions} object. If any assertions fail, this method + * throws an AssertionFailedError with the details of all the failed assertions. + * + *

**Usage** + *

{@code
+   * SoftAssertions softly = SoftAssertions.create();
+   * ...
+   * softly.assertAll();
+   * }
+ * + * @since v1.38 + */ + void assertAll(); +} + From ff623ab5c20b4f786b609917a1a3969e8536292f Mon Sep 17 00:00:00 2001 From: Umair Chagani Date: Fri, 25 Aug 2023 17:11:45 -0400 Subject: [PATCH 7/8] feat(soft-assertions): Exclude mockito tests from docker run --- .../com/microsoft/playwright/TestSoftAPIResponseAssertions.java | 2 ++ .../com/microsoft/playwright/TestSoftLocatorAssertions.java | 2 ++ .../java/com/microsoft/playwright/TestSoftPageAssertions.java | 2 ++ tools/test-local-installation/create_project_and_run_tests.sh | 2 +- 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/playwright/src/test/java/com/microsoft/playwright/TestSoftAPIResponseAssertions.java b/playwright/src/test/java/com/microsoft/playwright/TestSoftAPIResponseAssertions.java index c1dc6ebf6..26db96f98 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestSoftAPIResponseAssertions.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestSoftAPIResponseAssertions.java @@ -4,6 +4,7 @@ import com.microsoft.playwright.impl.APIResponseAssertionsImpl; import com.microsoft.playwright.impl.APIResponseAssertionsImplProxy; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; @@ -15,6 +16,7 @@ import static org.mockito.Mockito.verify; // The only thing we want to verify in these tests is that the correct method was called +@Tag("mockito") @ExtendWith(MockitoExtension.class) public class TestSoftAPIResponseAssertions { @Mock diff --git a/playwright/src/test/java/com/microsoft/playwright/TestSoftLocatorAssertions.java b/playwright/src/test/java/com/microsoft/playwright/TestSoftLocatorAssertions.java index 1a1e4c99d..b913c26ff 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestSoftLocatorAssertions.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestSoftLocatorAssertions.java @@ -4,6 +4,7 @@ import com.microsoft.playwright.impl.LocatorAssertionsImpl; import com.microsoft.playwright.impl.LocatorAssertionsImplProxy; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; @@ -17,6 +18,7 @@ import static org.mockito.Mockito.verify; // The only thing we want to verify in these tests is that the correct method was called +@Tag("mockito") @ExtendWith(MockitoExtension.class) public class TestSoftLocatorAssertions { @Mock diff --git a/playwright/src/test/java/com/microsoft/playwright/TestSoftPageAssertions.java b/playwright/src/test/java/com/microsoft/playwright/TestSoftPageAssertions.java index 63696ad26..53fc41b15 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestSoftPageAssertions.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestSoftPageAssertions.java @@ -4,6 +4,7 @@ import com.microsoft.playwright.impl.PageAssertionsImpl; import com.microsoft.playwright.impl.PageAssertionsImplProxy; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; @@ -17,6 +18,7 @@ import static org.mockito.Mockito.verify; // The only thing we want to verify in these tests is that the correct method was called +@Tag("mockito") @ExtendWith(MockitoExtension.class) public class TestSoftPageAssertions { @Mock diff --git a/tools/test-local-installation/create_project_and_run_tests.sh b/tools/test-local-installation/create_project_and_run_tests.sh index 525ca924f..1300d6549 100755 --- a/tools/test-local-installation/create_project_and_run_tests.sh +++ b/tools/test-local-installation/create_project_and_run_tests.sh @@ -14,6 +14,6 @@ cp -R ../../driver-bundle/src/test/ $PROJECT_DIR/src/ cp -R ../../playwright/src/test/ $PROJECT_DIR/src/ cd $PROJECT_DIR -mvn test --no-transfer-progress +mvn test -DexcludedGroups=mockito --no-transfer-progress rm -rf $PROJECT_DIR From e7c39400589ccbed9838f954f4d0f5c81ebb6700 Mon Sep 17 00:00:00 2001 From: Umair Chagani Date: Sat, 26 Aug 2023 19:03:38 -0400 Subject: [PATCH 8/8] feat(soft-assertions): Add mockito to docker test pom --- .../create_project_and_run_tests.sh | 2 +- tools/test-local-installation/pom.xml | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/tools/test-local-installation/create_project_and_run_tests.sh b/tools/test-local-installation/create_project_and_run_tests.sh index 1300d6549..525ca924f 100755 --- a/tools/test-local-installation/create_project_and_run_tests.sh +++ b/tools/test-local-installation/create_project_and_run_tests.sh @@ -14,6 +14,6 @@ cp -R ../../driver-bundle/src/test/ $PROJECT_DIR/src/ cp -R ../../playwright/src/test/ $PROJECT_DIR/src/ cd $PROJECT_DIR -mvn test -DexcludedGroups=mockito --no-transfer-progress +mvn test --no-transfer-progress rm -rf $PROJECT_DIR diff --git a/tools/test-local-installation/pom.xml b/tools/test-local-installation/pom.xml index 19502d572..33b1fcc7f 100644 --- a/tools/test-local-installation/pom.xml +++ b/tools/test-local-installation/pom.xml @@ -13,6 +13,7 @@ 5.7.0 UTF-8 1.5.1 + 4.11.0 @@ -43,6 +44,12 @@ Java-WebSocket ${websocket.version} + + org.mockito + mockito-junit-jupiter + ${mockito.version} + test +