Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/test/java/cz/czechitas/automation/ExampleTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,9 @@ void icoFieldTest(String icoValue) {
browser.headerMenu.goToKindergartenAndSchoolSection();
browser.orderSection.insertICO(icoValue);
}

@Test
void navigateToParentInstructionsAndFormsTest() {
browser.headerMenu.goToInstructionsAndFormsForParentSection();
}
Comment on lines +38 to +41

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Find all instances of navigateToParentInstructionsAndFormsTest across the test suite

# Search for the test method definition
rg -n "void navigateToParentInstructionsAndFormsTest\(\)" --type=java

Repository: czechitas/java-test-automation

Length of output: 298


Remove the duplicated test navigateToParentInstructionsAndFormsTest

navigateToParentInstructionsAndFormsTest exists in both src/test/java/cz/czechitas/automation/MyFirstTest.java (line 14) and src/test/java/cz/czechitas/automation/ExampleTest.java (line 39). Keep a single copy to avoid maintenance overhead and confusion, and delete the duplicate from one class.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/java/cz/czechitas/automation/ExampleTest.java` around lines 38 - 41,
Remove the duplicate test method navigateToParentInstructionsAndFormsTest found
in class ExampleTest and keep the single authoritative copy in MyFirstTest;
locate the method navigateToParentInstructionsAndFormsTest in
src/test/java/cz/czechitas/automation/ExampleTest.java and delete that method
(the one calling browser.headerMenu.goToInstructionsAndFormsForParentSection()),
then run tests to ensure no other references break and remove any now-unused
imports or setup in ExampleTest if they become unnecessary.

}
193 changes: 193 additions & 0 deletions src/test/java/cz/czechitas/automation/MyFirstTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
package cz.czechitas.automation;

import org.junit.jupiter.api.Test;

final class MyFirstTest extends TestRunner {

private void login() {
browser.loginSection.clickLoginMenuLink();
browser.loginSection.insertEmail("manka.rumova@yahoo.com");
browser.loginSection.insertPassword("Hovinko123");
browser.loginSection.clickLoginButton();
}
@Test
void navigateToParentInstructionsAndFormsTest() {
browser.headerMenu.goToInstructionsAndFormsForParentSection();
}

@Test
void orderSuburbanCampTest() {
browser.headerMenu.goToKindergartenAndSchoolSection();
browser.orderSection.selectSuburbanCampOption();
}
@Test
void navigateAllMenuSectionsTest() {
browser.headerMenu.goToHomePage();
browser.headerMenu.goToContactsSection();
browser.headerMenu.goToInstructionsAndFormsForParentSection();
browser.headerMenu.goToCreateApplicationSection();
browser.headerMenu.goToInstructionsAndFormsForTeacherSection();
browser.headerMenu.goToKindergartenAndSchoolSection();
}
@Test
void fillICOTest() {
browser.headerMenu.goToKindergartenAndSchoolSection();
browser.orderSection.insertICO("22834958");
}
@Test
void createApplicationTest() {
browser.loginSection.clickLoginMenuLink();
browser.loginSection.insertEmail("manka.rumova@yahoo.com");
browser.loginSection.insertPassword("Hovinko123");
browser.loginSection.clickLoginButton();
browser.applicationSection.clickCreateNewApplicationButton();
browser.applicationSection.selectProgrammingSection();
browser.applicationSection.clickCreatePythonApplicationButton();
}
Comment on lines +38 to +46

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Use the login() helper to avoid code duplication.

Lines 39-42 duplicate the login logic that's already extracted in the login() helper method (lines 7-12). Using the helper improves maintainability.

♻️ Suggested refactor
     `@Test`
     void createApplicationTest() {
-        browser.loginSection.clickLoginMenuLink();
-        browser.loginSection.insertEmail("manka.rumova@yahoo.com");
-        browser.loginSection.insertPassword("Hovinko123");
-        browser.loginSection.clickLoginButton();
+        login();
         browser.applicationSection.clickCreateNewApplicationButton();
         browser.applicationSection.selectProgrammingSection();
         browser.applicationSection.clickCreatePythonApplicationButton();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
void createApplicationTest() {
browser.loginSection.clickLoginMenuLink();
browser.loginSection.insertEmail("manka.rumova@yahoo.com");
browser.loginSection.insertPassword("Hovinko123");
browser.loginSection.clickLoginButton();
browser.applicationSection.clickCreateNewApplicationButton();
browser.applicationSection.selectProgrammingSection();
browser.applicationSection.clickCreatePythonApplicationButton();
}
void createApplicationTest() {
login();
browser.applicationSection.clickCreateNewApplicationButton();
browser.applicationSection.selectProgrammingSection();
browser.applicationSection.clickCreatePythonApplicationButton();
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/java/cz/czechitas/automation/MyFirstTest.java` around lines 38 - 46,
createApplicationTest() duplicates the login steps that are already implemented
in the login() helper (defined near lines 7-12); remove the explicit calls to
browser.loginSection.insertEmail / insertPassword / clickLoginMenuLink /
clickLoginButton in createApplicationTest() and replace them with a single call
to login(), then keep the subsequent applicationSection calls
(clickCreateNewApplicationButton, selectProgrammingSection,
clickCreatePythonApplicationButton) unchanged so the test reuses the helper and
avoids duplication.

@Test
void checkProgrammingTileTest() {
asserter.checkProgrammingSectionPresence();
}
@Test
void checkRegistrationButtonTest() {
browser.headerMenu.goToCreateApplicationSection();
asserter.checkRegistrationButtonPresence();
}
@Test
void checkPaymentMethodTest() {
login();
browser.applicationSection.openFirstApplicationDetailsPage();
asserter.applicationDetailSection.checkPaymentMethod("Bankovní převod");
}
@Test
void orderWithICOAndSchoolInNatureTest() {
browser.headerMenu.goToKindergartenAndSchoolSection();
asserter.checkPageUrl("www.czechitas.cz");
browser.orderSection.insertICO("22834958");
asserter.orderSection.checkIcoFieldContainsValue("22834958");
browser.orderSection.selectSchoolInNatureOption();
browser.orderSection.insertChildrenCount(15);
}
@Test
void checkApplicationColumnsTest() {
login();
browser.headerMenu.goToApplicationsSection();
asserter.applicationSection.checkColumnExists("Jméno", "Kategorie");
}
@Test
void complexApplicationTest() {
login();
browser.headerMenu.goToApplicationsSection();
browser.applicationSection.clickCreateNewApplicationButton();
browser.applicationSection.selectProgrammingSection();
browser.applicationSection.clickCreatePythonApplicationButton();
browser.applicationDetailsSection.selectTerm("08.06. - 19.06.2026");
browser.applicationDetailsSection.insertStudentFirstName("Jan");
browser.applicationDetailsSection.insertStudentLastName("Testovaci");
browser.applicationDetailsSection.insertBirthdate("01.01.2015");
browser.applicationDetailsSection.insertNote("Testovaci poznamka");
browser.applicationDetailsSection.selectCashPaymentMethod();
browser.applicationDetailsSection.clickAcceptTermsCheckbox();
browser.applicationDetailsSection.clickCreateApplicationButton();
asserter.applicationDetailSection.checkTerm("08.06. - 19.06.2026");
asserter.applicationDetailSection.checkFirstName("Jan");
asserter.applicationDetailSection.checkLastName("Testovaci");
asserter.applicationDetailSection.checkDateOfBirth("01.01.2015");
asserter.applicationDetailSection.checkNote("Testovaci poznamka");
}
@Test
void searchAndEditApplicationTest() {
login();
browser.headerMenu.goToApplicationsSection();
browser.applicationSection.search("Tester001");
browser.applicationSection.clickEditFirstApplicationButton();
browser.applicationDetailsSection.selectBankTransferPaymentMethod();
browser.applicationDetailsSection.clickEditApplicationButton();
browser.applicationSection.search("Tester001");
browser.applicationSection.openFirstApplicationDetailsPage();
asserter.applicationDetailSection.checkPaymentMethod("Bankovní převod");
asserter.applicationDetailSection.checkRemainingAmountToPay("2 490 Kč");
asserter.applicationDetailSection.checkMessageContainsStudentLastName("Tester001");
}
@Test
void twoUsersApplicationTest() {
// Prihlaseni jako prvni uzivatel
login();

// Vygenerovani nahodneho jmena a ulozeni do pormenne
var randomPrijmeni = browser.generateRandomName(10);

// Vytvoreni prihlasky
browser.headerMenu.goToApplicationsSection();
browser.applicationSection.clickCreateNewApplicationButton();
browser.applicationSection.selectProgrammingSection();
browser.applicationSection.clickCreatePythonApplicationButton();
browser.waitFor(3);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Replace hard wait with explicit wait.

The 3-second waitFor(3) is a hard-coded sleep that makes the test slower and potentially flaky. Consider using an explicit wait for the specific condition you're waiting for (e.g., waiting for a specific element or state to be ready).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/java/cz/czechitas/automation/MyFirstTest.java` at line 125, Replace
the hard sleep call browser.waitFor(3) in MyFirstTest with an explicit wait for
the specific condition or element you need, e.g. remove browser.waitFor(3) and
use a WebDriverWait / ExpectedConditions (or the project's browser.waitUntil
equivalent) to wait for the target element/state (by its locator or a helper
method that returns a boolean) to be visible/clickable/present before
proceeding; this keeps the test fast and robust.

browser.applicationDetailsSection.selectTerm("08.06. - 19.06.2026");
browser.applicationDetailsSection.insertStudentFirstName("Test");
browser.applicationDetailsSection.insertStudentLastName(randomPrijmeni);
browser.applicationDetailsSection.insertBirthdate("01.01.2015");
browser.applicationDetailsSection.insertNote("test");
browser.applicationDetailsSection.selectCashPaymentMethod();
browser.applicationDetailsSection.clickAcceptTermsCheckbox();
browser.applicationDetailsSection.clickCreateApplicationButton();

// Overeni z eprihlaska existuje
browser.headerMenu.goToApplicationsSection();
browser.applicationSection.search(randomPrijmeni);
asserter.applicationSection.checkNumberOfApplications(1);

// Odhlaseni
browser.loginSection.logout();

// Prihlaseni
browser.loginSection.clickLoginMenuLink();
browser.loginSection.insertEmail("peky@email.cz");
browser.loginSection.insertPassword("Hovinko123");
browser.loginSection.clickLoginButton();

// Overeni z eprihlaska prvniho uzivatele neexistuje
browser.headerMenu.goToApplicationsSection();
browser.applicationSection.search(randomPrijmeni);
asserter.applicationSection.checkApplicationsTableIsEmpty();
}

@Test
void changePasswordTest() {
var noveHeslo = "NoveHeslo123";
var puvodniHeslo = "Hovinko123";

// Prihlaseni
browser.loginSection.clickLoginMenuLink();
browser.loginSection.insertEmail("peky@email.cz");
browser.loginSection.insertPassword(puvodniHeslo);
browser.loginSection.clickLoginButton();

// Zmena hesla
browser.profileSection.goToProfilePage();
browser.profileSection.insertPassword(noveHeslo);
browser.profileSection.insertPasswordVerification(noveHeslo);
browser.profileSection.clickChangeButton();

// Prodleva nez zmizi pop up
browser.waitFor(9);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Replace 9-second hard wait with explicit wait for popup dismissal.

The 9-second hard-coded sleep significantly slows down the test and is unreliable. The popup might disappear sooner or take longer. Use an explicit wait that polls for the popup element to become invisible or stale.

🔧 Suggested improvement

Replace the hard wait with an explicit wait that polls for the popup to disappear. For example (assuming the popup has a predictable selector):

// Instead of: browser.waitFor(9);
// Use explicit wait for popup to disappear, e.g.:
// browser.waitForElementToBeInvisible(".popup-selector", 10);

Check if your test framework provides a utility for waiting on element invisibility.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/java/cz/czechitas/automation/MyFirstTest.java` at line 173, The test
uses a 9-second hard wait via browser.waitFor(9) which is slow and flaky;
replace that call in MyFirstTest (the location using browser.waitFor(9)) with an
explicit wait that polls until the popup element is gone or stale (use the test
framework's invisibility/staleness helper, e.g.
browser.waitForElementToBeInvisible("<popup-selector>", timeout) or
WebDriverWait
until(ExpectedConditions.invisibilityOfElementLocated(By.cssSelector("<popup-selector>")))
), ensure you pick the correct popup selector and set a reasonable timeout (e.g.
10s) and remove the hard-coded wait.


// Odhlaseni
browser.loginSection.logout();

// Prihlaseni s novym heslem
browser.loginSection.clickLoginMenuLink();
browser.loginSection.insertEmail("peky@email.cz");
browser.loginSection.insertPassword(noveHeslo);
browser.loginSection.clickLoginButton();

// Overeni prihlaseni
asserter.checkIsLoggedIn();

// Zmena hesla zpet na puvodni
browser.profileSection.goToProfilePage();
browser.profileSection.insertPassword(puvodniHeslo);
browser.profileSection.insertPasswordVerification(puvodniHeslo);
browser.profileSection.clickChangeButton();
}
Comment on lines +155 to +192

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Password change test lacks proper cleanup on failure.

If the test fails after changing the password (line 170) but before changing it back (line 191), the user account peky@email.cz will be left with the new password, potentially breaking subsequent test runs. Consider using a try-finally block or a test lifecycle hook (@AfterEach) to ensure the password is always reset, or use a dedicated test user account that can be reset independently.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/java/cz/czechitas/automation/MyFirstTest.java` around lines 155 -
192, The changePasswordTest currently changes the account password but may fail
before restoring it; wrap the test flow so the password reset always runs (e.g.,
put the steps that set the new password and verify login inside try and perform
the restore in a finally block), or move the restore logic into an `@AfterEach`
method that uses the same variables (puvodniHeslo, noveHeslo) and calls the same
page actions (browser.profileSection.goToProfilePage(), insertPassword(),
insertPasswordVerification(), clickChangeButton()) and login/logout helpers
(browser.loginSection.logout(), clickLoginMenuLink(), insertEmail(),
insertPassword(), clickLoginButton()) to ensure the account is reset even if
asserter.checkIsLoggedIn() or later steps fail.

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@ public final class AssertionFacade {
private final ElementFinderInterface elementFinder;
public final ApplicationAssertion applicationSection;
public final ApplicationDetailAssertion applicationDetailSection;

public final OrderAssertion orderSection;
public AssertionFacade(WebDriver webDriver)
{
this.elementFinder = new ElementFinder(webDriver);
this.applicationSection = new ApplicationAssertion(elementFinder);
this.applicationDetailSection = new ApplicationDetailAssertion(elementFinder);
this.orderSection = new OrderAssertion(elementFinder);
}

public void checkPageUrl(String url) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package cz.czechitas.automation.assertion;

import cz.czechitas.automation.ElementFinderInterface;

import javax.annotation.ParametersAreNonnullByDefault;
import java.util.Objects;

import static org.assertj.core.api.Assertions.assertThat;

@ParametersAreNonnullByDefault
public class OrderAssertion {

private final ElementFinderInterface elementFinder;

OrderAssertion(ElementFinderInterface elementFinder) {
this.elementFinder = Objects.requireNonNull(elementFinder);
}

public void checkIcoFieldContainsValue(String ico) {
var icoField = elementFinder.findByCssSelector("#ico");
assertThat(icoField.getAttribute("value")).isEqualTo(ico);
}
}