aboutsummaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/java/webui/ApplicationTest.java20
-rw-r--r--src/test/java/webui/PantryItemTest.java99
-rw-r--r--src/test/java/webui/pages/ApplicationPage.java50
-rw-r--r--src/test/java/webui/pages/IndexPage.java128
-rw-r--r--src/test/java/webui/pages/components/AddItemComponent.java121
-rw-r--r--src/test/resources/application.properties5
6 files changed, 423 insertions, 0 deletions
diff --git a/src/test/java/webui/ApplicationTest.java b/src/test/java/webui/ApplicationTest.java
new file mode 100644
index 0000000..a486f8f
--- /dev/null
+++ b/src/test/java/webui/ApplicationTest.java
@@ -0,0 +1,20 @@
+package webui;
+
+import java.net.URL;
+
+import com.microsoft.playwright.BrowserContext;
+
+import io.quarkiverse.playwright.InjectPlaywright;
+import io.quarkiverse.playwright.WithPlaywright;
+import io.quarkus.test.common.http.TestHTTPResource;
+
+@WithPlaywright
+public class ApplicationTest {
+
+ @InjectPlaywright
+ BrowserContext context;
+
+ @TestHTTPResource("/")
+ URL indexLocation;
+
+}
diff --git a/src/test/java/webui/PantryItemTest.java b/src/test/java/webui/PantryItemTest.java
new file mode 100644
index 0000000..71948b8
--- /dev/null
+++ b/src/test/java/webui/PantryItemTest.java
@@ -0,0 +1,99 @@
+package webui;
+
+import org.junit.jupiter.api.Test;
+
+import static com.microsoft.playwright.assertions.PlaywrightAssertions.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.List;
+
+import com.microsoft.playwright.Locator;
+
+import dev.submelon.model.PantryItem;
+import io.quarkiverse.quinoa.testing.QuinoaTestProfiles;
+import io.quarkus.test.junit.QuarkusTest;
+import io.quarkus.test.junit.TestProfile;
+import webui.pages.IndexPage;
+import webui.pages.components.AddItemComponent;
+
+@QuarkusTest
+@TestProfile(QuinoaTestProfiles.Enable.class)
+public class PantryItemTest extends ApplicationTest {
+
+ private static PantryItem[] testItems = new PantryItem[] {
+ PantryItem.builder()
+ .name("Flour")
+ .description("White unbleached")
+ .quantity(12.4d)
+ .quantityUnitType("cups")
+ .build(),
+ PantryItem.builder()
+ .name("Ponzu Sauce")
+ .quantity(4d)
+ .quantityUnitType("oz")
+ .build()
+ };
+
+ @Test
+ public void testLanding() {
+ // Arrange
+ final IndexPage page = new IndexPage(context.newPage());
+
+ // Act
+ page.loadAndVerifyPage(indexLocation);
+
+ // Assert
+ page.checkItemTableIsEmpty();
+
+ // Check add item button is visible and enabled
+ Locator addButton = page.getAddItemButton();
+ assertThat(addButton).isVisible();
+ assertThat(addButton).isEnabled();
+ }
+
+ @Test
+ public void testAddItemCancel() {
+ // Arrange
+ final PantryItem testItem = testItems[0];
+ final IndexPage page = new IndexPage(context.newPage());
+
+ // Act
+ page.loadAndVerifyPage(indexLocation);
+ page.checkItemTableIsEmpty();
+
+ AddItemComponent addItem = AddItemComponent.open(page);
+ addItem.enterPantryItem(testItem);
+ addItem.cancel();
+
+ // Assert
+ page.checkItemTableIsEmpty();
+ }
+
+ @Test
+ public void testAddItemSubmit() {
+ // Arrange
+ final PantryItem testItem = testItems[0];
+ final IndexPage page = new IndexPage(context.newPage());
+
+ // Act
+ page.loadAndVerifyPage(indexLocation);
+ page.checkItemTableIsEmpty();
+
+ AddItemComponent addItem = AddItemComponent.open(page);
+ addItem.enterPantryItem(testItem);
+ addItem.submit();
+
+ // Assert
+ page.validateAddItemNotification(testItem);
+
+ List<Locator> items = page.getCurrentItems(1);
+ assertEquals(1, items.size());
+
+ Locator newItem = items.get(0);
+ assertThat(newItem).containsText(testItem.getName());
+ assertThat(newItem).containsText(testItem.getDescription());
+ assertThat(newItem).containsText(testItem.getQuantity().toString());
+ assertThat(newItem).containsText(testItem.getQuantityUnitType());
+ }
+
+}
diff --git a/src/test/java/webui/pages/ApplicationPage.java b/src/test/java/webui/pages/ApplicationPage.java
new file mode 100644
index 0000000..2182a5d
--- /dev/null
+++ b/src/test/java/webui/pages/ApplicationPage.java
@@ -0,0 +1,50 @@
+package webui.pages;
+
+import static com.microsoft.playwright.assertions.PlaywrightAssertions.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.net.URL;
+
+import com.microsoft.playwright.Locator;
+import com.microsoft.playwright.Page;
+import com.microsoft.playwright.Response;
+import com.microsoft.playwright.options.AriaRole;
+
+/**
+ * Provide abstract class to track Pantry-wide locators, components, integrations, and tests
+ */
+public abstract class ApplicationPage {
+
+ private static final String TOAST_DIV_SELECTOR = "div#toast-holder";
+
+ protected final Page page;
+
+ public ApplicationPage(Page page) {
+ this.page = page;
+ }
+
+ /**
+ * Navigate to page with table of Pantry Items
+ */
+ public void loadAndVerifyPage(URL location, String title) {
+ Response response = page.navigate(location.toString());
+ assertEquals("OK", response.statusText());
+
+ page.waitForLoadState();
+
+ assertThat(page).hasTitle(title);
+ }
+
+
+ /**
+ * Assert that a notification is displayed with the specified header and text
+ */
+ public Locator findAndValidateNotification(final String header, final String text) {
+ Locator specifiedNotification = page.locator(TOAST_DIV_SELECTOR)
+ .getByRole(AriaRole.ALERT)
+ .filter(new Locator.FilterOptions().setHasText(text));
+ assertThat(specifiedNotification).isVisible();
+ assertThat(specifiedNotification).containsText(header);
+ return specifiedNotification;
+ }
+} \ No newline at end of file
diff --git a/src/test/java/webui/pages/IndexPage.java b/src/test/java/webui/pages/IndexPage.java
new file mode 100644
index 0000000..ce9a5b6
--- /dev/null
+++ b/src/test/java/webui/pages/IndexPage.java
@@ -0,0 +1,128 @@
+package webui.pages;
+
+import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat;
+
+import java.net.URL;
+import java.util.List;
+
+import com.microsoft.playwright.Locator;
+import com.microsoft.playwright.Page;
+import com.microsoft.playwright.options.AriaRole;
+
+import dev.submelon.model.PantryItem;
+
+/**
+ * Provide locators and methodical tests for the index page of the Pantry application
+ */
+public class IndexPage extends ApplicationPage {
+
+ private static final String INDEX_PAGE_TITLE = "Pantry";
+
+ private static final String ADD_ITEM_LABEL = "Add Item";
+ private static final String ITEM_NAME_LABEL = "Item Name";
+ private static final String ITEM_DESCRIPTION_LABEL = "Item Description";
+ private static final String ITEM_QUANTITY_LABEL = "Item Quantity";
+ private static final String ITEM_QUANTITY_TYPE_LABEL = "Quantity Type";
+ private static final String SUBMIT_ITEM_LABEL = "Submit Item";
+ private static final String CANCEL_LABEL = "Cancel";
+
+ private static final String PANTRY_TABLE_ROW_SELECTOR = "css=table#tbl-pantry > tbody > tr";
+ private static final String EMPTY_TABLE_MESSAGE_SELECTOR = "div#tbl-msg-empty";
+
+ private static final String EMPTY_TABLE_MESSAGE_TEXT = "Nothing's in the pantry at the moment!";
+ private static final String ADD_ITEM_NOTIFICATION_HEADER = "Item added successfully";
+ private static final String ADD_ITEM_NOTIFICATION_TEMPLATE = "Stored \"%s\" in the pantry!";
+
+ public IndexPage(Page page) {
+ super(page);
+ }
+
+ /**
+ * Navigate to page with table of Pantry Items
+ */
+ public void loadAndVerifyPage(URL location) {
+ loadAndVerifyPage(location, INDEX_PAGE_TITLE);
+ }
+
+ /**
+ * Check table is empty with appropriate message
+ */
+ public void checkItemTableIsEmpty() {
+ Locator td = page.locator(EMPTY_TABLE_MESSAGE_SELECTOR);
+ assertThat(td).isVisible();
+ assertThat(td).containsText(EMPTY_TABLE_MESSAGE_TEXT);
+ }
+
+ /**
+ * Obtain a list of items or rows (`tr`s) in the Pantry Item table
+ */
+ public List<Locator> getCurrentItems(int numExpectedItems) {
+ if (numExpectedItems == 0) {
+ checkItemTableIsEmpty();
+ }
+
+ Locator table = page.locator(PANTRY_TABLE_ROW_SELECTOR)
+ .filter(new Locator.FilterOptions().setHasNotText(EMPTY_TABLE_MESSAGE_TEXT));
+ assertThat(table).hasCount(numExpectedItems);
+
+ return table.all();
+ }
+
+ /**
+ * Obtain the add item button on the index page
+ */
+ public Locator getAddItemButton() {
+ return page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName(ADD_ITEM_LABEL));
+ }
+
+ /**
+ * Obtain the item name input in the add item component
+ */
+ public Locator getItemNameInput() {
+ return page.getByLabel(ITEM_NAME_LABEL);
+ }
+
+ /**
+ * Obtain the item description input in the add item component
+ */
+ public Locator getItemDescriptionInput() {
+ return page.getByLabel(ITEM_DESCRIPTION_LABEL);
+ }
+
+ /**
+ * Obtain the item quantity input in the add item component
+ */
+ public Locator getItemQuantityInput() {
+ return page.getByLabel(ITEM_QUANTITY_LABEL);
+ }
+
+ /**
+ * Obtain the item quantity type input in the add item component
+ */
+ public Locator getQuantityTypeInput() {
+ return page.getByLabel(ITEM_QUANTITY_TYPE_LABEL);
+ }
+
+ /**
+ * Obtain the submit item button in the add item component
+ */
+ public Locator getSubmitItemButton() {
+ return page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName(SUBMIT_ITEM_LABEL));
+ }
+
+ /**
+ * Obtain the cancel button in the add item component
+ */
+ public Locator getCancelButton() {
+ return page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName(CANCEL_LABEL));
+ }
+
+ /**
+ * assert notification is displayed that item has been added
+ */
+ public Locator validateAddItemNotification(final PantryItem item) {
+ return findAndValidateNotification(ADD_ITEM_NOTIFICATION_HEADER,
+ String.format(ADD_ITEM_NOTIFICATION_TEMPLATE, item.getName()));
+ }
+
+}
diff --git a/src/test/java/webui/pages/components/AddItemComponent.java b/src/test/java/webui/pages/components/AddItemComponent.java
new file mode 100644
index 0000000..ba799fd
--- /dev/null
+++ b/src/test/java/webui/pages/components/AddItemComponent.java
@@ -0,0 +1,121 @@
+package webui.pages.components;
+
+import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat;
+
+import com.microsoft.playwright.Locator;
+
+import dev.submelon.model.PantryItem;
+import webui.pages.IndexPage;
+
+/**
+ * A component to add an item to the pantry on the index page
+ */
+public class AddItemComponent {
+
+ private Locator nameInput;
+ private Locator descriptionInput;
+ private Locator quantityInput;
+ private Locator quantityTypeInput;
+ private Locator submitButton;
+ private Locator cancelButton;
+
+ /**
+ * Opens the add item component on the index page and creates the instance
+ * of the AddItemComponent.
+ */
+ public static AddItemComponent open(final IndexPage page) {
+
+ // Check button is visible and enabled
+ Locator addButton = page.getAddItemButton();
+ assertThat(addButton).isVisible();
+ assertThat(addButton).isEnabled();
+
+ // make available add item component
+ addButton.click();
+
+ // verify initial state of inputs and buttons
+ assertThat(addButton).isHidden();
+
+ // find and assign inputs for the component
+ AddItemComponent component = new AddItemComponent();
+ component.nameInput = page.getItemNameInput();
+ component.descriptionInput = page.getItemDescriptionInput();
+ component.quantityInput = page.getItemQuantityInput();
+ component.quantityTypeInput = page.getQuantityTypeInput();
+
+ // find and assign buttons for the component
+ component.submitButton = page.getSubmitItemButton();
+ component.cancelButton = page.getCancelButton();
+
+ component.verifyOpen();
+
+ return component;
+ }
+
+ /**
+ * Enter values into the inputs based on a {@link PantryItem}
+ */
+ public void enterPantryItem(final PantryItem item) {
+ if (item.getName() != null) {
+ nameInput.fill(item.getName());
+ }
+ if (item.getDescription() != null) {
+ descriptionInput.fill(item.getDescription());
+ }
+ if (item.getQuantity() != null) {
+ quantityInput.fill(String.valueOf(item.getQuantity()));
+ }
+ if (item.getQuantityUnitType() != null) {
+ quantityTypeInput.fill(item.getQuantityUnitType());
+ }
+ }
+
+ /**
+ * Submits the item to the API and closes the add item component
+ */
+ public void submit() {
+ submitButton.click();
+
+ verifyClosed();
+ }
+
+ /**
+ * Closes the add item component without saving
+ */
+ public void cancel() {
+ cancelButton.click();
+
+ verifyClosed();
+ }
+
+ /**
+ * Verify the expected inputs and buttons appear as expected on opening
+ */
+ public void verifyOpen() {
+ assertThat(nameInput).isVisible();
+ assertThat(nameInput).isEditable();
+ assertThat(descriptionInput).isVisible();
+ assertThat(descriptionInput).isEditable();
+ assertThat(quantityInput).isVisible();
+ assertThat(quantityInput).isEditable();
+ assertThat(quantityTypeInput).isVisible();
+ assertThat(quantityTypeInput).isEditable();
+ assertThat(submitButton).isVisible();
+ assertThat(submitButton).isDisabled();
+ assertThat(cancelButton).isVisible();
+ assertThat(cancelButton).isEnabled();
+ }
+
+ /**
+ * Verify all of the expected inputs and buttons no longer appear
+ */
+ public void verifyClosed() {
+ assertThat(nameInput).isHidden();
+ assertThat(descriptionInput).isHidden();
+ assertThat(quantityInput).isHidden();
+ assertThat(quantityTypeInput).isHidden();
+ assertThat(submitButton).isHidden();
+ assertThat(cancelButton).isHidden();
+ }
+
+}
diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties
new file mode 100644
index 0000000..969f6ee
--- /dev/null
+++ b/src/test/resources/application.properties
@@ -0,0 +1,5 @@
+quarkus.http.test-port=8081
+quarkus.quinoa.package-manager-command.build-env.PUBLIC_ENV=prod
+quarkus.quinoa.package-manager-command.build-env.PUBLIC_HOST_ADDRESS=http://localhost:8081
+quarkus.quinoa.package-manager-command.build-env.PUBLIC_HEALTH_POLL=3600000
+quarkus.quinoa.package-manager-command.build-env.PUBLIC_ENTRIES_PER_PAGE=10