From 33a31b80f2540b5284188921071548a8432e97f7 Mon Sep 17 00:00:00 2001 From: Robert Goldmann <deadlocker@gmx.de> Date: Sun, 17 Oct 2021 22:57:24 +0200 Subject: [PATCH] #577 - added selenium tests --- .../transactions/transactionsMacros.ftl | 2 +- .../NewTransactionFromExistingOneTest.java | 172 ++++++++++++++++++ .../NewTransactionFromExistingOneTest.json | 104 +++++++++++ 3 files changed, 277 insertions(+), 1 deletion(-) create mode 100644 src/test/java/de/deadlocker8/budgetmaster/integration/selenium/NewTransactionFromExistingOneTest.java create mode 100644 src/test/resources/NewTransactionFromExistingOneTest.json diff --git a/src/main/resources/templates/transactions/transactionsMacros.ftl b/src/main/resources/templates/transactions/transactionsMacros.ftl index 264491513..0f79a9d61 100644 --- a/src/main/resources/templates/transactions/transactionsMacros.ftl +++ b/src/main/resources/templates/transactions/transactionsMacros.ftl @@ -53,7 +53,7 @@ <#if transaction.isEditable()> <@header.buttonFlat url='/transactions/' + transaction.ID?c + '/edit' icon='edit' localizationKey='' classes="no-padding text-default"/> <@header.buttonFlat url='/transactions/' + transaction.ID?c + '/requestDelete' icon='delete' localizationKey='' classes="no-padding text-default button-request-delete-transaction" isDataUrl=true/> - <@header.buttonFlat url='/transactions/' + transaction.ID?c + '/newFromExisting' icon='content_copy' localizationKey='' classes="no-padding text-default"/> + <@header.buttonFlat url='/transactions/' + transaction.ID?c + '/newFromExisting' icon='content_copy' localizationKey='' classes="no-padding text-default button-new-from-existing"/> </#if> </div> </#macro> diff --git a/src/test/java/de/deadlocker8/budgetmaster/integration/selenium/NewTransactionFromExistingOneTest.java b/src/test/java/de/deadlocker8/budgetmaster/integration/selenium/NewTransactionFromExistingOneTest.java new file mode 100644 index 000000000..eaddcace4 --- /dev/null +++ b/src/test/java/de/deadlocker8/budgetmaster/integration/selenium/NewTransactionFromExistingOneTest.java @@ -0,0 +1,172 @@ +package de.deadlocker8.budgetmaster.integration.selenium; + +import de.deadlocker8.budgetmaster.accounts.Account; +import de.deadlocker8.budgetmaster.accounts.AccountType; +import de.deadlocker8.budgetmaster.authentication.UserService; +import de.deadlocker8.budgetmaster.integration.helpers.IntegrationTestHelper; +import de.deadlocker8.budgetmaster.integration.helpers.SeleniumTestBase; +import de.deadlocker8.budgetmaster.integration.helpers.TransactionTestHelper; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; + +import java.io.File; +import java.util.Arrays; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class NewTransactionFromExistingOneTest extends SeleniumTestBase +{ + private IntegrationTestHelper helper; + + @BeforeAll + public void beforeAll() + { + helper = new IntegrationTestHelper(driver, port); + helper.start(); + helper.login(UserService.DEFAULT_PASSWORD); + helper.hideBackupReminder(); + helper.hideWhatsNewDialog(); + + String path = getClass().getClassLoader().getResource("NewTransactionFromExistingOneTest.json").getFile().replace("/", File.separator); + final Account account1 = new Account("DefaultAccount", AccountType.CUSTOM); + final Account account2 = new Account("Second Account", AccountType.CUSTOM); + + helper.uploadDatabase(path, Arrays.asList("Default Account", "Second Account"), List.of(account1, account2)); + } + + @BeforeEach + public void beforeEach() + { + driver.get(helper.getUrl() + "/transactions"); + + TransactionTestHelper.selectGlobalAccountByName(driver, "DefaultAccount"); + } + + private void gotoSpecificYearAndMonth(int year, String monthName) + { + driver.findElement(By.className("headline-date")).click(); + + WebDriverWait wait = new WebDriverWait(driver, 5); + wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("global-datepicker-select-year"))); + + By locator = By.xpath("//td[contains(@class, 'global-datepicker-item') and contains(text(),'" + year + "')]"); + driver.findElement(locator).click(); + + wait = new WebDriverWait(driver, 5); + wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("global-datepicker-select-month"))); + + locator = By.xpath("//td[contains(@class, 'global-datepicker-item') and contains(text(),'" + monthName + "')]"); + driver.findElement(locator).click(); + + String yearAndMonthCombined = monthName + " " + year; + wait = new WebDriverWait(driver, 5); + locator = By.xpath("//a[contains(@class, 'headline-date') and contains(text(),'" + yearAndMonthCombined + "')]"); + wait.until(ExpectedConditions.visibilityOfElementLocated(locator)); + } + + @Test + void test_newTransactionFromExisting_normal() + { + gotoSpecificYearAndMonth(2021, "October"); + + List<WebElement> transactionsRows = driver.findElements(By.cssSelector(".transaction-container .hide-on-med-and-down.transaction-row-top")); + List<WebElement> columns = transactionsRows.get(0).findElements(By.className("col")); + columns.get(5).findElement(By.className("button-new-from-existing")).click(); + + WebDriverWait wait = new WebDriverWait(driver, 5); + wait.until(ExpectedConditions.textToBePresentInElementLocated(By.cssSelector(".headline"), "New Transaction")); + + // assert + assertThat(driver.findElement(By.className("buttonExpenditure")).getAttribute("class")).contains("background-red"); + assertThat(driver.findElement(By.id("transaction-name")).getAttribute("value")).isEqualTo("Full normal"); + assertThat(driver.findElement(By.id("transaction-amount")).getAttribute("value")).isEqualTo("12.00"); + assertThat(driver.findElement(By.id("transaction-description")).getAttribute("value")).isEqualTo("lorem ipsum"); + assertThat(driver.findElement(By.cssSelector(".category-select-wrapper .custom-select-selected-item .category-circle")).getAttribute("data-value")).isEqualTo("3"); + + final List<WebElement> chips = driver.findElements(By.cssSelector("#transaction-chips .chip")); + assertThat(chips).hasSize(1); + assertThat(chips.get(0)).hasFieldOrPropertyWithValue("text", "123\nclose"); + + assertThat(driver.findElement(By.cssSelector(".account-select-wrapper .custom-select-selected-item .category-circle")).getAttribute("data-value")).isEqualTo("3"); + + // submit form + driver.findElement(By.id("button-save-transaction")).click(); + + wait = new WebDriverWait(driver, 5); + wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(".headline-date"))); + + // assert + assertThat(driver.getCurrentUrl()).endsWith("/transactions"); + } + + @Test + void test_newTransactionFromExisting_transfer() + { + gotoSpecificYearAndMonth(2021, "September"); + + List<WebElement> transactionsRows = driver.findElements(By.cssSelector(".transaction-container .hide-on-med-and-down.transaction-row-top")); + List<WebElement> columns = transactionsRows.get(0).findElements(By.className("col")); + columns.get(5).findElement(By.className("button-new-from-existing")).click(); + + WebDriverWait wait = new WebDriverWait(driver, 5); + wait.until(ExpectedConditions.textToBePresentInElementLocated(By.cssSelector(".headline"), "New Transfer")); + + // assert + assertThat(driver.findElement(By.id("transaction-name")).getAttribute("value")).isEqualTo("Full transfer"); + assertThat(driver.findElement(By.id("transaction-amount")).getAttribute("value")).isEqualTo("15.00"); + assertThat(driver.findElement(By.id("transaction-description")).getAttribute("value")).isEqualTo("dolor sit amet"); + assertThat(driver.findElement(By.cssSelector(".category-select-wrapper .custom-select-selected-item .category-circle")).getAttribute("data-value")).isEqualTo("3"); + + final List<WebElement> chips = driver.findElements(By.cssSelector("#transaction-chips .chip")); + assertThat(chips).hasSize(1); + assertThat(chips.get(0)).hasFieldOrPropertyWithValue("text", "456\nclose"); + + assertThat(driver.findElement(By.cssSelector(".account-select-wrapper .custom-select-selected-item .category-circle")).getAttribute("data-value")).isEqualTo("3"); + assertThat(driver.findElement(By.cssSelector(".transfer-account-select-wrapper .custom-select-selected-item .category-circle")).getAttribute("data-value")).isEqualTo("4"); + + // submit form + driver.findElement(By.id("button-save-transaction")).click(); + + wait = new WebDriverWait(driver, 5); + wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(".headline-date"))); + + // assert + assertThat(driver.getCurrentUrl()).endsWith("/transactions"); + } + + @Test + void test_newTransactionFromExisting_recurring() + { + gotoSpecificYearAndMonth(2021, "June"); + + List<WebElement> transactionsRows = driver.findElements(By.cssSelector(".transaction-container .hide-on-med-and-down.transaction-row-top")); + List<WebElement> columns = transactionsRows.get(0).findElements(By.className("col")); + columns.get(5).findElement(By.className("button-new-from-existing")).click(); + + WebDriverWait wait = new WebDriverWait(driver, 5); + wait.until(ExpectedConditions.textToBePresentInElementLocated(By.cssSelector(".headline"), "New Transaction")); + + // assert + assertThat(driver.findElement(By.id("transaction-name")).getAttribute("value")).isEqualTo("normal recurring"); + assertThat(driver.findElement(By.id("transaction-repeating-modifier")).getAttribute("value")).isEqualTo("1"); + assertThat(driver.findElement(By.id("transaction-repeating-modifier-type")).getAttribute("value")).isEqualTo("Months"); + + assertThat(driver.findElement(By.id("repeating-end-after-x-times")).isSelected()).isTrue(); + assertThat(driver.findElement(By.id("transaction-repeating-end-after-x-times-input")).getAttribute("value")).isEqualTo("1"); + + // submit form + driver.findElement(By.id("button-save-transaction")).click(); + + wait = new WebDriverWait(driver, 5); + wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(".headline-date"))); + + // assert + assertThat(driver.getCurrentUrl()).endsWith("/transactions"); + } +} \ No newline at end of file diff --git a/src/test/resources/NewTransactionFromExistingOneTest.json b/src/test/resources/NewTransactionFromExistingOneTest.json new file mode 100644 index 000000000..6cfb50e8b --- /dev/null +++ b/src/test/resources/NewTransactionFromExistingOneTest.json @@ -0,0 +1,104 @@ +{ + "TYPE": "BUDGETMASTER_DATABASE", + "VERSION": 7, + "categories": [ + { + "ID": 192, + "name": "Custom Category", + "color": "#ff9500", + "type": "CUSTOM" + }, + { + "ID": 190, + "name": "No Category", + "color": "#FFFFFF", + "type": "NONE" + }, + { + "ID": 191, + "name": "Rest", + "color": "#FFFF00", + "type": "REST" + } + ], + "accounts": [ + { + "ID": 169, + "name": "Placeholder", + "accountState": "FULL_ACCESS", + "type": "ALL" + }, + { + "ID": 170, + "name": "Default Account", + "accountState": "FULL_ACCESS", + "type": "CUSTOM" + }, + { + "ID": 171, + "name": "Second Account", + "accountState": "FULL_ACCESS", + "type": "CUSTOM" + } + ], + "transactions": [ + { + "amount": -1200, + "isExpenditure": true, + "date": "2021-10-17", + "accountID": 170, + "categoryID": 192, + "name": "Full normal", + "description": "lorem ipsum", + "tags": [ + { + "name": "123" + } + ] + }, + { + "amount": -1500, + "isExpenditure": true, + "date": "2021-09-17", + "accountID": 170, + "categoryID": 192, + "name": "Full transfer", + "description": "dolor sit amet", + "tags": [ + { + "name": "456" + } + ], + "transferAccountID": 171 + }, + { + "amount": -200, + "isExpenditure": true, + "date": "2021-06-17", + "accountID": 170, + "categoryID": 192, + "name": "normal recurring", + "description": "apple", + "tags": [ + { + "name": "789" + } + ], + "repeatingOption": { + "startDate": "2021-10-17", + "modifier": { + "quantity": 1, + "localizationKey": "repeating.modifier.months" + }, + "endOption": { + "localizationKey": "repeating.end.key.afterXTimes", + "times": 1 + } + } + } + ], + "templates": [], + "charts": [], + "images": [], + "icons": [] +} \ No newline at end of file -- GitLab