diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml
index 071a8d0..53a33e8 100644
--- a/.github/workflows/ci-build.yml
+++ b/.github/workflows/ci-build.yml
@@ -9,10 +9,10 @@ jobs:
steps:
- uses: actions/checkout@v3
- - name: Set up JDK 17
+ - name: Set up JDK 21
uses: actions/setup-java@v3
with:
- java-version: '17'
+ java-version: '21'
distribution: 'temurin'
- name: Build with Maven
run: mvn --batch-mode --update-snapshots verify -Pit
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..4942f8a
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+/target/
+/bin
+.project
diff --git a/README.md b/README.md
index 556c259..f94bf3c 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ To try/use Mopo, add following dependency to your pom.xml (or to Gradle build):
in.virit
mopo
- 0.0.1
+ test
+
+
+
+ com.vaadin
+ vaadin-dev
+ test
com.microsoft.playwright
playwright
- 1.44.0
+ 1.56.0
jakarta.servlet
jakarta.servlet-api
- 5.0.0
+
provided
commons-beanutils
commons-beanutils
- 1.9.4
+ 1.11.0
test
jar
@@ -101,7 +103,7 @@
org.hibernate.validator
hibernate-validator
- 8.0.0.Final
+ 9.1.0.Final
test
@@ -137,6 +139,11 @@
formatter-maven-plugin
2.12.2
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
org.apache.maven.plugins
maven-jar-plugin
@@ -177,9 +184,12 @@
org.apache.maven.plugins
maven-release-plugin
- 2.5.3
+ 3.1.1
+ true
+ false
release
+ deploy
@@ -191,20 +201,19 @@
- org.sonatype.plugins
- nexus-staging-maven-plugin
- 1.6.13
+ org.sonatype.central
+ central-publishing-maven-plugin
+ 0.9.0
true
- ossrh
- https://oss.sonatype.org/
- true
+ central
+ true
org.codehaus.mojo
flatten-maven-plugin
- 1.2.5
+ 1.7.0
oss
@@ -225,10 +234,36 @@
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 3.3.1
+
+
+ attach-sources
+
+ jar-no-fork
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 3.7.0
+
+
+ attach-javadocs
+
+ jar
+
+
+
+
org.apache.maven.plugins
maven-gpg-plugin
- 1.6
+ 3.2.7
sign-artifacts
@@ -317,4 +352,3 @@
-
diff --git a/src/main/java/in/virit/mopo/ComboBoxPw.java b/src/main/java/in/virit/mopo/ComboBoxPw.java
index a132d50..9850b27 100644
--- a/src/main/java/in/virit/mopo/ComboBoxPw.java
+++ b/src/main/java/in/virit/mopo/ComboBoxPw.java
@@ -1,7 +1,7 @@
package in.virit.mopo;
import com.microsoft.playwright.Locator;
-
+import java.util.List;
import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat;
/**
@@ -28,7 +28,31 @@ public ComboBoxPw(Locator gridLocator) {
*/
public void filterAndSelectFirst(String filter) {
filter(filter);
+
+ // seems to be needed with latest Vaadin versions
+ assertThat(root).not().hasAttribute("loading", "");
+
+ root.locator("input").press("Enter");
+
+ // seems to be needed with latest Vaadin versions
+ assertThat(root).not().hasAttribute("opened", "");
+ }
+
+ /**
+ * Filters the MultiSelectComboBox by searching for each term provided in the filter
+ * list and selects the first suggestion for each term.
+ *
+ * @param filterList a list of strings representing the terms to be searched
+ * for and selected in the ComboBox
+ */
+ public void filterAndSelectFirstMultiSelect(List filterList) {
+ root.locator("input").press("Escape");
+ for(String filter: filterList) {
+ filter(filter);
root.locator("input").press("Enter");
+ root.locator("input").press("Escape");
+ }
+ root.locator("input").press("Escape");
}
/**
@@ -68,7 +92,7 @@ public ComboBoxPw selectOption(String option) {
*/
public Locator selectionDropdown() {
// there can be only one
- return root.page().locator("vaadin-combo-box-overlay");
+ return root.page().locator("vaadin-combo-box-scroller");
}
/**
@@ -80,5 +104,14 @@ public Locator openDropDown() {
root.locator("#toggleButton").click();
return selectionDropdown();
}
+
+ /**
+ * Returns the selected value for the ComboBox
+ *
+ * @return the selected value
+ */
+ public String getSelection() {
+ return root.locator("input").inputValue();
+ }
}
diff --git a/src/main/java/in/virit/mopo/DatePickerPw.java b/src/main/java/in/virit/mopo/DatePickerPw.java
index 15152ba..369b297 100644
--- a/src/main/java/in/virit/mopo/DatePickerPw.java
+++ b/src/main/java/in/virit/mopo/DatePickerPw.java
@@ -1,9 +1,9 @@
package in.virit.mopo;
-import com.microsoft.playwright.Locator;
-
import java.time.LocalDate;
+import com.microsoft.playwright.Locator;
+
/**
* A helper class to work with vaadin-date-picker component.
*/
@@ -30,28 +30,27 @@ public DatePickerPw(Locator gridLocator) {
public LocalDate getValue() {
String str = (String) root.evaluate("db => db.value");
try {
- return LocalDate.parse(str);
- } catch (java.time.format.DateTimeParseException e) {
+ return LocalDate.parse(str);
+ } catch (java.time.format.DateTimeParseException e) {
return null;
}
}
- /**
- * Sets the value of the field.
- *
- * @param value the value to be set
- */
- public void setValue(LocalDate value) {
- root.evaluate("db => db.value = '%s'".formatted(value));
+ /**
+ * Sets the value of the field.
+ *
+ * @param value the value to be set
+ */
+ public void setValue(LocalDate value) {
+ root.evaluate("db => db.value = '%s'".formatted(value));
}
- /**
- * Returns the raw string value in the field.
- *
- * @return the string value as it is formatted in the field. Note, this may
- * be locale dependent.
- */
- public String getInputString() {
+ /**
+ * Returns the raw string value in the field.
+ *
+ * @return the string value as it is formatted in the field. Note, this may be locale dependent.
+ */
+ public String getInputString() {
return root.locator("input").inputValue();
}
-}
+}
\ No newline at end of file
diff --git a/src/main/java/in/virit/mopo/DateTimePickerPw.java b/src/main/java/in/virit/mopo/DateTimePickerPw.java
index 8b72122..ab78930 100644
--- a/src/main/java/in/virit/mopo/DateTimePickerPw.java
+++ b/src/main/java/in/virit/mopo/DateTimePickerPw.java
@@ -28,6 +28,9 @@ public DateTimePickerPw(Locator gridLocator) {
*/
public void setValue(LocalDateTime value) {
root.evaluate("db => db.value = '%s'".formatted(value));
+ // needed since 25...
+ root.evaluate("db => db.querySelector(\"input\").focus()");
+ root.evaluate("db => db.querySelector(\"input\").blur()");
}
/**
diff --git a/src/main/java/in/virit/mopo/GridPw.java b/src/main/java/in/virit/mopo/GridPw.java
index b6f58e4..959cf13 100644
--- a/src/main/java/in/virit/mopo/GridPw.java
+++ b/src/main/java/in/virit/mopo/GridPw.java
@@ -1,5 +1,8 @@
package in.virit.mopo;
+import java.util.ArrayList;
+import java.util.List;
+
import com.microsoft.playwright.Locator;
import com.microsoft.playwright.Page;
@@ -13,7 +16,8 @@ public class GridPw {
/**
* Creates a Grid page object for the given grid locator.
*
- * @param gridLocator the Playwright locator for the grid
+ * @param gridLocator
+ * the Playwright locator for the grid
*/
public GridPw(Locator gridLocator) {
this.root = gridLocator;
@@ -22,7 +26,8 @@ public GridPw(Locator gridLocator) {
/**
* Creates a Grid page object for the first grid on the page.
*
- * @param page the Playwright page
+ * @param page
+ * the Playwright page
*/
public GridPw(Page page) {
this(page.locator("vaadin-grid"));
@@ -34,78 +39,95 @@ public GridPw(Page page) {
* @return the number of rows
*/
public int getRenderedRowCount() {
- Integer evaluate = (Integer) root.elementHandle().evaluate("e => e._getRenderedRows().length");
+ Integer evaluate = (Integer) root.elementHandle()
+ .evaluate("e => e._getRenderedRows().length");
return evaluate;
}
+ /**
+ * Returns a list of RowPw objects representing the grid rows.
+ *
+ * @return A List of RowPw objects representing the grid rows.
+ */
+ public List getGridRows() {
+ List allRows = new ArrayList<>();
+ for (int i = 0; i < getRenderedRowCount(); i++) {
+ allRows.add(getRow(i));
+ }
+ return allRows;
+ }
+
/**
* Returns the index of the first visible row
*
* @return the index.
*/
public int getFirstVisibleRowIndex() {
- return (Integer) root.elementHandle().evaluate("e => e._firstVisibleIndex");
+ return (Integer) root.elementHandle()
+ .evaluate("e => e._firstVisibleIndex");
}
/**
* Scrolls the grid to the given index.
*
- * @param index the row index to scroll to
+ * @param index
+ * the row index to scroll to
*/
public void scrollToIndex(int index) {
root.elementHandle().evaluate("e => e.scrollToIndex(" + index + ")");
// FIXME this don't seem to be stable, but
// 10*100ms timeout seems to do the trick most of the time
- int value = (Integer) root.evaluate("""
- g => {
- return new Promise((resolve, reject) => {
- var x = 0;
- const isDoneLoading = () => {
- return !g.$connector.hasRootRequestQueue()
- };
-
- const isVaadinConnectionActive = () => {
- if (window.Vaadin && window.Vaadin.Flow && window.Vaadin.Flow.clients) {
- var clients = window.Vaadin.Flow.clients;
- for (var client in clients) {
- if (clients[client].isActive()) {
- return false;
+ int value = (Integer) root.evaluate(
+ """
+ g => {
+ return new Promise((resolve, reject) => {
+ var x = 0;
+ const isDoneLoading = () => {
+ return !g.$connector.hasRootRequestQueue()
+ };
+
+ const isVaadinConnectionActive = () => {
+ if (window.Vaadin && window.Vaadin.Flow && window.Vaadin.Flow.clients) {
+ var clients = window.Vaadin.Flow.clients;
+ for (var client in clients) {
+ if (clients[client].isActive()) {
+ return false;
+ }
+ }
+ return true;
+ } else if (window.Vaadin && window.Vaadin.Flow && window.Vaadin.Flow.devServerIsNotLoaded) {
+ return false;
+ } else {
+ return true;
+ }
+ };
+
+ if (isDoneLoading() && !isVaadinConnectionActive()) {
+ resolve(x);
+ return;
}
- }
- return true;
- } else if (window.Vaadin && window.Vaadin.Flow && window.Vaadin.Flow.devServerIsNotLoaded) {
- return false;
- } else {
- return true;
- }
- };
-
- if (isDoneLoading() && !isVaadinConnectionActive()) {
- resolve(x);
- return;
- }
-
- var intervalID = window.setInterval(function () {
- if (isDoneLoading() && !isVaadinConnectionActive()) {
- window.clearInterval(intervalID);
- resolve(x+1);
- } else {
- if (++x === 10) {
- window.clearInterval(intervalID);
- resolve(-1);
- }
- }
- }, 100);
- });
- }""");
- // System.out.println("RETURN value = " + value);
+
+ var intervalID = window.setInterval(function () {
+ if (isDoneLoading() && !isVaadinConnectionActive()) {
+ window.clearInterval(intervalID);
+ resolve(x+1);
+ } else {
+ if (++x === 10) {
+ window.clearInterval(intervalID);
+ resolve(-1);
+ }
+ }
+ }, 100);
+ });
+ }""");
}
/**
* Selects the given row.
*
- * @param rowIndex the row index to select
+ * @param rowIndex
+ * the row index to select
*/
public void selectRow(int rowIndex) {
String script = """
@@ -117,16 +139,18 @@ public void selectRow(int rowIndex) {
var row = rows[0];
grid.activeItem = row._item;
}
- """.formatted(rowIndex);
+ """
+ .formatted(rowIndex);
root.elementHandle().evaluate(script);
}
/**
* Returns a RowPw helper representing the row defined by the given index.
*
- * @param rowIndex the row index
+ * @param rowIndex
+ * the row index
* @return the RowPw for editing the UI state or to get cell locators for
- * assertions.
+ * assertions.
*/
public RowPw getRow(int rowIndex) {
if (!isRowInView(rowIndex)) {
@@ -138,9 +162,10 @@ public RowPw getRow(int rowIndex) {
/**
* Checks if the given row is in the visible viewport.
*
- * @param rowIndex the row to check
+ * @param rowIndex
+ * the row to check
* @return true if the row is at least partially in view,
- * false otherwise
+ * false otherwise
*/
public boolean isRowInView(int rowIndex) {
return (getFirstVisibleRowIndex() <= rowIndex
@@ -153,7 +178,8 @@ public boolean isRowInView(int rowIndex) {
* @return the index
*/
public int getLastVisibleRowIndex() {
- return (Integer) root.elementHandle().evaluate("e => e._lastVisibleIndex");
+ return (Integer) root.elementHandle()
+ .evaluate("e => e._lastVisibleIndex");
}
/**
@@ -172,23 +198,33 @@ private RowPw(int rowIndex) {
/**
* Gets the cell locator at the given index.
*
- * @param cellIndex the cell index (0-based, unlike the CSS nth-child
- * selector, whose designer should be hung by the balls, in case they
- * have any)
+ * @param cellIndex
+ * the cell index (0-based, unlike the CSS nth-child
+ * selector, whose designer should be hung by the balls, in
+ * case they have any)
* @return the cell locator
*/
public Locator getCell(int cellIndex) {
- int indexInVirtualTable = (Integer) root.evaluate("g => g._getRenderedRows().indexOf(g._getRenderedRows().filter(r => r.index == %s)[0]);".formatted(rowIndex));
- indexInVirtualTable += 1; // 1-based :-)
- String name = root.locator("#items tr:nth-child(%s) td:nth-child(%s) slot".formatted(indexInVirtualTable, cellIndex + 1))
- .getAttribute("name");
- return root.locator("vaadin-grid-cell-content[slot='%s']".formatted(name));
+ int indexInVirtualTable =
+ (Integer)
+ root.evaluate(
+ "g => g._getRenderedRows().indexOf(g._getRenderedRows().filter(r => r.index == %s)[0]);"
+ .formatted(rowIndex));
+ Locator row =
+ root.locator("#items tr")
+ .filter(new Locator.FilterOptions().setVisible(true))
+ .nth(indexInVirtualTable);
+ String name =
+ row.locator("td:nth-child(%s) slot".formatted(cellIndex + 1)).getAttribute("name");
+ return root.locator("vaadin-grid-cell-content[slot='%s']".formatted(name));
}
+
/**
* Gets the cell with the given header text.
*
- * @param headerText the header text
+ * @param headerText
+ * the header text
* @return the cell locator
*/
public Locator getCell(String headerText) {
diff --git a/src/main/java/in/virit/mopo/Mopo.java b/src/main/java/in/virit/mopo/Mopo.java
index 107364f..10cc64b 100644
--- a/src/main/java/in/virit/mopo/Mopo.java
+++ b/src/main/java/in/virit/mopo/Mopo.java
@@ -16,6 +16,7 @@
public class Mopo {
private final Page page;
+ private List clientSideErrors = new ArrayList<>();
/**
* Constructs a new Mopo for given page
@@ -40,7 +41,7 @@ public static void waitForConnectionToSettle(Page page) {
/**
* Waits until the client-server communication by Vaadin has settled.
*
- * @param page the page on which Vaadin app is expected to be run
+ * @param page the page on which Vaadin app is expected to be run
* @param minWait the minimum wait time spent to watch if client-server communication starts
*/
public static void waitForConnectionToSettle(Page page, int minWait) {
@@ -60,7 +61,9 @@ public static void waitForConnectionToSettle(Page page, int minWait) {
* Asserts that there are no JS errors in the dev console.
*
* @param page the page to be checked
+ * @deprecated this method depends on dev mode, consider using {@link #failOnClientSideErrors()} ()} and {@link #trackClientSideErrors()} that use browser console.
*/
+ @Deprecated
public static void assertNoJsErrors(Page page) {
try {
@@ -80,6 +83,33 @@ public static void assertNoJsErrors(Page page) {
}
}
+ /**
+ * Starts monitoring browser console and errors and collects
+ * those for further inspection (e.g. with {@link #getClientSideErrors()} or {@link #failOnClientSideErrors()}).
+ */
+ public void trackClientSideErrors() {
+ page.waitForTimeout(1000);
+ page.onConsoleMessage(msg -> {
+ if (msg.type().equals("error")) {
+ clientSideErrors.add(msg.text());
+ }
+ });
+
+ page.onPageError(error -> {
+ clientSideErrors.add(error);
+ });
+ }
+
+ /**
+ * Returns the list of console errors that have been logged since the
+ * {@link #trackClientSideErrors()} was called.
+ *
+ * @return a list of console messages that are errors
+ */
+ public List getClientSideErrors() {
+ return clientSideErrors;
+ }
+
/**
* Waits until the client-server communication by Vaadin
* has settled.
@@ -90,7 +120,10 @@ public void waitForConnectionToSettle() {
/**
* Asserts that there are no JS errors in the dev console.
+ *
+ * @deprecated this method depends on dev mode, consider using {@link #failOnClientSideErrors()} ()} and {@link #trackClientSideErrors()} that use browser console.
*/
+ @Deprecated
public void assertNoJsErrors() {
assertNoJsErrors(page);
}
@@ -180,4 +213,19 @@ public void click(String selector) {
page.locator(selector).click();
waitForConnectionToSettle();
}
+
+ /**
+ * Asserts that there are no client-side errors in the console.
+ * Throws a RuntimeException if there are any errors.
+ */
+ public void failOnClientSideErrors() {
+ List consoleErrors = getClientSideErrors();
+ if (!consoleErrors.isEmpty()) {
+ StringBuilder sb = new StringBuilder("There are JS errors in the console:\n");
+ for (var msg : consoleErrors) {
+ sb.append(msg).append("\n");
+ }
+ throw new RuntimeException("JS errors discovered: "+ sb.toString());
+ }
+ }
}
diff --git a/src/main/java/in/virit/mopo/TimePickerPw.java b/src/main/java/in/virit/mopo/TimePickerPw.java
new file mode 100644
index 0000000..22f772f
--- /dev/null
+++ b/src/main/java/in/virit/mopo/TimePickerPw.java
@@ -0,0 +1,77 @@
+package in.virit.mopo;
+
+import com.microsoft.playwright.Locator;
+import com.microsoft.playwright.Page;
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Locale;
+/**
+ * A helper class to work with vaadin-time-picker component.
+ */
+public class TimePickerPw {
+
+ private final Locator root;
+ private final Page page;
+ private String timeFormat;
+
+ /**
+ * Constructs a TimePicker instance with the specified Page and element ID.
+ *
+ * @param page
+ * The Page to which the time picker belongs.
+ * @param id
+ * The ID of the time picker element.
+ */
+ public TimePickerPw(Page page, String id) {
+ this.page = page;
+ this.root = page.locator("#" + id + " > input");
+ }
+
+ /**
+ * Sets the value of the time picker to the specified LocalTime. The
+ * formatted time is entered into the input field, and "Enter" is pressed.
+ * Additionally, it waits for the time picker overlay to be hidden after
+ * setting the value.
+ *
+ * @param value
+ * The LocalTime to be set.
+ */
+ public void setValue(LocalTime value) {
+ String formattedTime = (timeFormat == null ? value.toString()
+ : DateTimeFormatter.ofPattern(timeFormat, Locale.ROOT).format(value));
+
+ root.fill(formattedTime);
+ root.press("Enter");
+
+ // Wait for the time picker overlay to be hidden
+ Page.WaitForSelectorOptions options = new Page.WaitForSelectorOptions();
+ options.setState(options.state.HIDDEN);
+ page.waitForSelector("vaadin-time-picker-overlay", options);
+ }
+
+ /**
+ * Returns the value from the client side and parses it as
+ * {@link LocalDate} using a {@link DateTimeFormatter}.
+ *
+ * @return the current value of the field
+ */
+ public LocalTime getValue() {
+ String value = root.inputValue();
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern(timeFormat, Locale.ROOT);
+
+ return timeFormat == null ? LocalTime.parse(value)
+ : LocalTime.parse(value, formatter);
+ }
+
+ /**
+ * Sets the format to be used when setting the time value.
+ *
+ * @param format
+ * The format to be set.
+ */
+ public void setDateFormat(String format) {
+ timeFormat = format;
+ }
+
+}
diff --git a/src/test/java/firitin/TestRunner.java b/src/test/java/firitin/TestRunner.java
new file mode 100644
index 0000000..82fd4c1
--- /dev/null
+++ b/src/test/java/firitin/TestRunner.java
@@ -0,0 +1,24 @@
+package firitin;
+import java.util.Collections;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+// This annotation tells Spring to start up and look for Views and AppShell
+@SpringBootApplication
+public class TestRunner {
+
+ public static void main(String[] args) {
+ // This launches the web server on localhost:9998
+ SpringApplication app = new SpringApplication(TestRunner.class);
+
+ // Force port 9998
+ app.setDefaultProperties(Collections.singletonMap("server.port", "9998"));
+
+ app.run(args);
+
+ System.out.println("----------------------------------------------");
+ System.out.println(" Test Server Running at http://localhost:9998");
+ System.out.println("----------------------------------------------");
+ }
+}
diff --git a/src/test/java/firitin/pw/AddonHelpersIT.java b/src/test/java/firitin/pw/AddonHelpersIT.java
index a0a823d..735531b 100644
--- a/src/test/java/firitin/pw/AddonHelpersIT.java
+++ b/src/test/java/firitin/pw/AddonHelpersIT.java
@@ -6,6 +6,7 @@
import com.microsoft.playwright.Playwright;
import in.virit.mopo.Mopo;
import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
@@ -21,9 +22,6 @@ public class AddonHelpersIT {
static Playwright playwright = Playwright.create();
- static {
- }
-
private Browser browser;
private Page page;
private Mopo mopo;
@@ -47,7 +45,7 @@ public void closePlaywright() {
browser.close();
}
- @Test
+ //@Test // Disabled because with latest Vaadin version copilot/devmode don't seem to load anymore and probably non-functional
public void doRandomStuffAndChangeFirstRow() throws InterruptedException {
page.navigate("http://localhost:" + port + "/addonhelpers");
@@ -68,12 +66,41 @@ public void doRandomStuffAndChangeFirstRow() throws InterruptedException {
assertThat(page.locator("vaadin-dev-tools>div.error")).isAttached();
}
+ @Test
+ public void checkJsErrorsViaConsole() throws InterruptedException {
+ // Note, start tracking console errors only here, as Vaadin gives one favicon related error by default
+ mopo.trackClientSideErrors();
+ page.navigate("http://localhost:" + port + "/addonhelpers");
+
+ mopo.waitForConnectionToSettle();
+
+ mopo.getClientSideErrors().clear(); // Vaadin gives one favicon related error by default, so clear it
+
+ Assertions.assertEquals(0, mopo.getClientSideErrors().size(),
+ "There should be no console errors after the page has loaded");
+
+ // a helper message to fail the test if there is a JS error
+ page.getByText("Throw JS exception").click();
+
+ assertThat(page.getByText("Error should have been thrown!")).isVisible();
+
+ // You could call this in the beginning of the test, but testing it is nasty
+ // mopo.failOnClientSideErrorsOnClose();
- @Test
+ // This is pretty much the same as above but inverted for testing
+ boolean thrown = false;
+ try {
+ mopo.failOnClientSideErrors();
+ } catch (RuntimeException e) {
+ thrown = true;
+ }
+ Assertions.assertTrue(thrown, "There should be an exception thrown");
+ }
+
+ @Test
public void listView() {
// One could now open each of these and e.g. check for not JS errors
List developmentTimeViewNames = mopo.getViewsReportedByDevMode(browser, "http://localhost:" + port + "/");
developmentTimeViewNames.forEach(System.out::println);
-
}
}
diff --git a/src/test/java/firitin/pw/ComboBoxIT.java b/src/test/java/firitin/pw/ComboBoxIT.java
index 51bb5b2..5661cc6 100644
--- a/src/test/java/firitin/pw/ComboBoxIT.java
+++ b/src/test/java/firitin/pw/ComboBoxIT.java
@@ -59,12 +59,14 @@ public void rawUsage() throws InterruptedException {
Locator cb = page.locator("input[role='combobox']");
cb.fill("foo");
+ // seems to be needed with latest Vaadin versions
+ page.waitForTimeout(1000);
cb.press("Enter");
assertThat(value).containsText("foo");
cb.fill("ba");
- Locator overlay = page.locator("vaadin-combo-box-overlay");
+ Locator overlay = page.locator("vaadin-combo-box-scroller");
// this should be third option & visible
overlay.getByText("baz").click();
diff --git a/src/test/java/firitin/pw/GridPlaywrightIT.java b/src/test/java/firitin/pw/GridPlaywrightIT.java
index 1205255..65c0484 100644
--- a/src/test/java/firitin/pw/GridPlaywrightIT.java
+++ b/src/test/java/firitin/pw/GridPlaywrightIT.java
@@ -99,6 +99,11 @@ public void doRandomStuffAndChangeFirstRow() throws InterruptedException {
// Get the first cell of the first row in Grid and check text
// TODO add API to get cell by column header text
+ page.waitForTimeout(1000);
+ page.waitForTimeout(1000);
+
+ mopo.waitForConnectionToSettle();
+
assertThat(grid.getRow(0).getCell(0)).hasText(newFirstName);
assertThat(grid.getRow(0).getCell("First Name")).hasText(newFirstName);
diff --git a/src/test/java/firitin/ui/AddOnHelpersView.java b/src/test/java/firitin/ui/AddOnHelpersView.java
index 1a72f70..097944d 100644
--- a/src/test/java/firitin/ui/AddOnHelpersView.java
+++ b/src/test/java/firitin/ui/AddOnHelpersView.java
@@ -1,6 +1,7 @@
package firitin.ui;
import com.vaadin.flow.component.button.Button;
+import com.vaadin.flow.component.html.Paragraph;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.Route;
@@ -13,6 +14,7 @@ public AddOnHelpersView() {
add(new Button("Throw JS exception", e -> {
// deliberately cause a JS exception
getElement().executeJs("window.foo();");
+ add(new Paragraph("Error should have been thrown!"));
}));
}
}
diff --git a/src/test/java/firitin/ui/AppShell.java b/src/test/java/firitin/ui/AppShell.java
index 4b11901..38f965d 100644
--- a/src/test/java/firitin/ui/AppShell.java
+++ b/src/test/java/firitin/ui/AppShell.java
@@ -1,9 +1,13 @@
package firitin.ui;
+import com.vaadin.flow.component.dependency.StyleSheet;
import com.vaadin.flow.component.page.AppShellConfigurator;
import com.vaadin.flow.component.page.Push;
+import com.vaadin.flow.theme.lumo.Lumo;
@Push
+@StyleSheet(Lumo.STYLESHEET)
+@StyleSheet(Lumo.UTILITY_STYLESHEET)
public class AppShell implements AppShellConfigurator {
}
\ No newline at end of file