diff --git a/src/main/java/com/example/slabiak/appointmentscheduler/model/DayPlan.java b/src/main/java/com/example/slabiak/appointmentscheduler/model/DayPlan.java index 0be2dda..8f32161 100644 --- a/src/main/java/com/example/slabiak/appointmentscheduler/model/DayPlan.java +++ b/src/main/java/com/example/slabiak/appointmentscheduler/model/DayPlan.java @@ -19,35 +19,51 @@ public List timePeroidsWithBreaksExcluded() { List breaks = getBreaks(); if (!breaks.isEmpty()) { - ArrayList toAdd = new ArrayList(); - for (TimePeroid break1 : breaks) { - if (break1.getStart().isBefore(workingHours.getStart())) { - break1.setStart(workingHours.getStart()); - } - if (break1.getEnd().isAfter(workingHours.getEnd())) { - break1.setEnd(workingHours.getEnd()); - } - for (TimePeroid peroid : timePeroidsWithBreaksExcluded) { - if (break1.getStart().equals(peroid.getStart()) && break1.getEnd().isAfter(peroid.getStart()) && break1.getEnd().isBefore(peroid.getEnd())) { - peroid.setStart(break1.getEnd()); - } - if (break1.getStart().isAfter(peroid.getStart()) && break1.getStart().isBefore(peroid.getEnd()) && break1.getEnd().equals(peroid.getEnd())) { - peroid.setEnd(break1.getStart()); - } - if (break1.getStart().isAfter(peroid.getStart()) && break1.getEnd().isBefore(peroid.getEnd())) { - toAdd.add(new TimePeroid(peroid.getStart(), break1.getStart())); - peroid.setStart(break1.getEnd()); - } - } - } - timePeroidsWithBreaksExcluded.addAll(toAdd); + adjustBreaksWithinWorkingHours(timePeroidsWithBreaksExcluded); Collections.sort(timePeroidsWithBreaksExcluded); } - return timePeroidsWithBreaksExcluded; } + private void adjustBreaksWithinWorkingHours(List timePeroidsWithBreaksExcluded) { + ArrayList toAdd = new ArrayList<>(); + for (TimePeroid break1 : getBreaks()) { + adjustBreakStart(break1); + adjustBreakEnd(break1); + + for (TimePeroid peroid : timePeroidsWithBreaksExcluded) { + handleBreakOverlap(break1, peroid, toAdd); + } + } + timePeroidsWithBreaksExcluded.addAll(toAdd); + } + + private void adjustBreakStart(TimePeroid break1) { + if (break1.getStart().isBefore(workingHours.getStart())) { + break1.setStart(workingHours.getStart()); + } + } + + private void adjustBreakEnd(TimePeroid break1) { + if (break1.getEnd().isAfter(workingHours.getEnd())) { + break1.setEnd(workingHours.getEnd()); + } + } + + private void handleBreakOverlap(TimePeroid break1, TimePeroid peroid, List toAdd) { + if (break1.getStart().equals(peroid.getStart()) && break1.getEnd().isAfter(peroid.getStart()) && break1.getEnd().isBefore(peroid.getEnd())) { + peroid.setStart(break1.getEnd()); + } + if (break1.getStart().isAfter(peroid.getStart()) && break1.getStart().isBefore(peroid.getEnd()) && break1.getEnd().equals(peroid.getEnd())) { + peroid.setEnd(break1.getStart()); + } + if (break1.getStart().isAfter(peroid.getStart()) && break1.getEnd().isBefore(peroid.getEnd())) { + toAdd.add(new TimePeroid(peroid.getStart(), break1.getStart())); + peroid.setStart(break1.getEnd()); + } + } + public TimePeroid getWorkingHours() { return workingHours; } diff --git a/src/main/java/com/example/slabiak/appointmentscheduler/service/impl/AppointmentServiceImpl.java b/src/main/java/com/example/slabiak/appointmentscheduler/service/impl/AppointmentServiceImpl.java index 98826d4..da8028e 100644 --- a/src/main/java/com/example/slabiak/appointmentscheduler/service/impl/AppointmentServiceImpl.java +++ b/src/main/java/com/example/slabiak/appointmentscheduler/service/impl/AppointmentServiceImpl.java @@ -323,29 +323,39 @@ public String getCancelNotAllowedReason(int userId, int appointmentId) { } if (appointment.getProvider().equals(user)) { - if (!appointment.getStatus().equals(AppointmentStatus.SCHEDULED)) { - return "Only appoinmtents with scheduled status can be cancelled."; - } else { - return null; - } + return getCancelNotAllowedReasonForProvider(appointment); } if (appointment.getCustomer().equals(user)) { - if (!appointment.getStatus().equals(AppointmentStatus.SCHEDULED)) { - return "Only appoinmtents with scheduled status can be cancelled."; - } else if (LocalDateTime.now().plusDays(1).isAfter(appointment.getStart())) { - return "Appointments which will be in less than 24 hours cannot be canceled."; - } else if (!appointment.getWork().getEditable()) { - return "This type of appointment can be canceled only by Provider."; - } else if (getCanceledAppointmentsByCustomerIdForCurrentMonth(userId).size() >= NUMBER_OF_ALLOWED_CANCELATIONS_PER_MONTH) { - return "You can't cancel this appointment because you exceeded maximum number of cancellations in this month."; - } else { - return null; - } + return getCancelNotAllowedReasonForCustomer(appointment, userId); } + return null; } + private String getCancelNotAllowedReasonForProvider(Appointment appointment) { + if (!appointment.getStatus().equals(AppointmentStatus.SCHEDULED)) { + return "Only appointments with scheduled status can be cancelled."; + } else { + return null; + } + } + + private String getCancelNotAllowedReasonForCustomer(Appointment appointment, int userId) { + if (!appointment.getStatus().equals(AppointmentStatus.SCHEDULED)) { + return "Only appointments with scheduled status can be cancelled."; + } else if (LocalDateTime.now().plusDays(1).isAfter(appointment.getStart())) { + return "Appointments which will be in less than 24 hours cannot be canceled."; + } else if (!appointment.getWork().getEditable()) { + return "This type of appointment can be canceled only by Provider."; + } else if (getCanceledAppointmentsByCustomerIdForCurrentMonth(userId).size() >= NUMBER_OF_ALLOWED_CANCELATIONS_PER_MONTH) { + return "You can't cancel this appointment because you exceeded the maximum number of cancellations in this month."; + } else { + return null; + } + } + + @Override public int getNumberOfCanceledAppointmentsForUser(int userId) { return appointmentRepository.findCanceledByUser(userId).size(); diff --git a/src/main/java/com/example/slabiak/appointmentscheduler/util/PdfGeneratorUtil.java b/src/main/java/com/example/slabiak/appointmentscheduler/util/PdfGeneratorUtil.java index 87e47bf..b903a83 100644 --- a/src/main/java/com/example/slabiak/appointmentscheduler/util/PdfGeneratorUtil.java +++ b/src/main/java/com/example/slabiak/appointmentscheduler/util/PdfGeneratorUtil.java @@ -26,40 +26,47 @@ public PdfGeneratorUtil(SpringTemplateEngine templateEngine, @Value("${base.url} } public File generatePdfFromInvoice(Invoice invoice) { + Context ctx = createContextWithInvoice(invoice); + String processedHtml = processHtmlTemplate(ctx); + ITextRenderer renderer = createAndInitializeRenderer(processedHtml); + + try { + return createPdfFile(renderer); + } catch (IOException | DocumentException e) { + e.printStackTrace(); + } + + return null; + } + + private Context createContextWithInvoice(Invoice invoice) { Context ctx = new Context(); ctx.setVariable("invoice", invoice); - String processedHtml = templateEngine.process("email/pdf/invoice", ctx); + return ctx; + } + private String processHtmlTemplate(Context ctx) { + return templateEngine.process("email/pdf/invoice", ctx); + } + + private ITextRenderer createAndInitializeRenderer(String processedHtml) { ITextRenderer renderer = new ITextRenderer(); renderer.setDocumentFromString(processedHtml, baseUrl); renderer.layout(); + return renderer; + } + private File createPdfFile(ITextRenderer renderer) throws IOException, DocumentException { String fileName = UUID.randomUUID().toString(); - FileOutputStream os = null; - try { - final File outputFile = File.createTempFile(fileName, ".pdf"); - os = new FileOutputStream(outputFile); + File outputFile = File.createTempFile(fileName, ".pdf"); + + try (FileOutputStream os = new FileOutputStream(outputFile)) { renderer.createPDF(os, false); renderer.finishPDF(); - return outputFile; - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } catch (DocumentException e) { - e.printStackTrace(); - } finally { - if (os != null) { - try { - os.close(); - - } catch (IOException e) { - e.printStackTrace(); - } - } } - return null; + + return outputFile; } } diff --git a/src/test/java/com/example/slabiak/appointmentscheduler/service/user/RetailCustomerUserServiceTest.java b/src/test/java/com/example/slabiak/appointmentscheduler/service/user/RetailCustomerUserServiceTest.java index b4e8e9d..107e752 100644 --- a/src/test/java/com/example/slabiak/appointmentscheduler/service/user/RetailCustomerUserServiceTest.java +++ b/src/test/java/com/example/slabiak/appointmentscheduler/service/user/RetailCustomerUserServiceTest.java @@ -20,198 +20,200 @@ import java.util.Optional; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class RetailCustomerUserServiceTest { - @Mock - private BCryptPasswordEncoder passwordEncoder; - - @Mock - private RoleRepository roleRepository; - - @Mock - private RetailCustomerRepository retailCustomerRepository; - - @InjectMocks - private UserServiceImpl userService; - - UserForm retailUserForm; - RetailCustomer retailCustomer; - Optional optionalRetailCustomer; - - private int userId; - private String userName; - private String password; - private String matchingPassword; - private String firstName; - private String lastName; - private String email; - private String mobile; - private String street; - private String postcode; - private String city; - - String passwordEncoded; - - private String roleNameCustomer; - private String roleNameRetailCustomer; - private Role roleCustomer; - private Role roleRetailCustomer; - Collection retailCustomerRoles; - - - @Before - public void initObjects() { - - userId = 1; - userName = "username"; - password = "password"; - matchingPassword = "password"; - firstName = "firstname"; - lastName = "lastname"; - email = "email@example.com"; - mobile = "123456789"; - street = "street"; - postcode = "12-345"; - city = "city"; - - passwordEncoded = "xxxx"; - - retailUserForm = new UserForm(); - retailUserForm.setUserName(userName); - retailUserForm.setPassword(password); - retailUserForm.setMatchingPassword(matchingPassword); - retailUserForm.setFirstName(firstName); - retailUserForm.setLastName(lastName); - retailUserForm.setEmail(email); - retailUserForm.setMobile(mobile); - retailUserForm.setStreet(street); - retailUserForm.setPostcode(postcode); - retailUserForm.setCity(city); - retailUserForm.setId(userId); - - roleNameCustomer = "ROLE_CUSTOMER"; - roleNameRetailCustomer = "ROLE_CUSTOMER_RETAIL"; - roleCustomer = new Role(roleNameCustomer); - roleRetailCustomer = new Role(roleNameRetailCustomer); - retailCustomerRoles = new HashSet<>(); - retailCustomerRoles.add(roleCustomer); - retailCustomerRoles.add(roleRetailCustomer); - - - } - - @Test - public void shouldSaveNewRetailCustomer() { - ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(RetailCustomer.class); - userService.saveNewRetailCustomer(retailUserForm); - - verify(retailCustomerRepository, times(1)).save(argumentCaptor.capture()); - } - - @Test - public void shouldEncodePasswordWhenForNewRetailCustomer() { - when(passwordEncoder.encode(password)).thenReturn(passwordEncoded); - - ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(RetailCustomer.class); - userService.saveNewRetailCustomer(retailUserForm); - - verify(retailCustomerRepository, times(1)).save(argumentCaptor.capture()); - assertEquals(argumentCaptor.getValue().getPassword(), passwordEncoded); - } - - @Test - public void userFormDataShouldMatchRetailCustomerObject() { - - ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(RetailCustomer.class); - userService.saveNewRetailCustomer(retailUserForm); - - verify(retailCustomerRepository, times(1)).save(argumentCaptor.capture()); - assertEquals(argumentCaptor.getValue().getUserName(), retailUserForm.getUserName()); - assertEquals(argumentCaptor.getValue().getFirstName(), retailUserForm.getFirstName()); - assertEquals(argumentCaptor.getValue().getLastName(), retailUserForm.getLastName()); - assertEquals(argumentCaptor.getValue().getEmail(), retailUserForm.getEmail()); - assertEquals(argumentCaptor.getValue().getMobile(), retailUserForm.getMobile()); - assertEquals(argumentCaptor.getValue().getStreet(), retailUserForm.getStreet()); - assertEquals(argumentCaptor.getValue().getCity(), retailUserForm.getCity()); - assertEquals(argumentCaptor.getValue().getPostcode(), retailUserForm.getPostcode()); - } - - @Test - public void shouldAssignTwoRolesForRetailCustomer() { - doReturn(roleRetailCustomer).when(roleRepository).findByName(roleNameRetailCustomer); - doReturn(roleCustomer).when(roleRepository).findByName(roleNameCustomer); - - ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(RetailCustomer.class); - userService.saveNewRetailCustomer(retailUserForm); - - verify(retailCustomerRepository, times(1)).save(argumentCaptor.capture()); - assertEquals(argumentCaptor.getValue().getRoles().size(), 2); - } - - @Test - public void shouldAssignCorrectRolesForRetailCustomer() { - doReturn(roleRetailCustomer).when(roleRepository).findByName(roleNameRetailCustomer); - doReturn(roleCustomer).when(roleRepository).findByName(roleNameCustomer); - - ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(RetailCustomer.class); - userService.saveNewRetailCustomer(retailUserForm); - - verify(retailCustomerRepository, times(1)).save(argumentCaptor.capture()); - assertEquals(argumentCaptor.getValue().hasRole(roleNameRetailCustomer), true); - assertEquals(argumentCaptor.getValue().hasRole(roleNameCustomer), true); - } - - @Test - public void shouldUpdateRetailCustomerProfileData() { - RetailCustomer customerToBeUpdated = new RetailCustomer(); - customerToBeUpdated.setId(userId); - - doReturn(customerToBeUpdated).when(retailCustomerRepository).getOne(userId); - - ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(RetailCustomer.class); - userService.updateRetailCustomerProfile(retailUserForm); - verify(retailCustomerRepository, times(1)).save(argumentCaptor.capture()); - assertEquals(argumentCaptor.getValue().getFirstName(), retailUserForm.getFirstName()); - assertEquals(argumentCaptor.getValue().getLastName(), retailUserForm.getLastName()); - assertEquals(argumentCaptor.getValue().getEmail(), retailUserForm.getEmail()); - assertEquals(argumentCaptor.getValue().getMobile(), retailUserForm.getMobile()); - assertEquals(argumentCaptor.getValue().getStreet(), retailUserForm.getStreet()); - assertEquals(argumentCaptor.getValue().getCity(), retailUserForm.getCity()); - assertEquals(argumentCaptor.getValue().getPostcode(), retailUserForm.getPostcode()); - } - - @Test - public void shouldNotAffectUsernameAndPasswordAndRolesWhileRetailCustomerProfileUpdate() { - RetailCustomer customerToBeUpdated = new RetailCustomer(); - String currentUsername = "username2"; - String currentPassword = "password2"; - customerToBeUpdated.setUserName(currentUsername); - customerToBeUpdated.setPassword(currentPassword); - customerToBeUpdated.setRoles(retailCustomerRoles); - doReturn(customerToBeUpdated).when(retailCustomerRepository).getOne(userId); - - ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(RetailCustomer.class); - userService.updateRetailCustomerProfile(retailUserForm); - verify(retailCustomerRepository, times(1)).save(argumentCaptor.capture()); - assertEquals(argumentCaptor.getValue().getUserName(), currentUsername); - assertEquals(argumentCaptor.getValue().getPassword(), currentPassword); - assertEquals(argumentCaptor.getValue().getRoles(), retailCustomerRoles); - } - - @Test - public void shouldFindRetailCustomerById() { - retailCustomer = new RetailCustomer(); - retailCustomer.setId(userId); - retailCustomer.setUserName(userName); - optionalRetailCustomer = Optional.of(retailCustomer); - when(retailCustomerRepository.findById(userId)).thenReturn(optionalRetailCustomer); - assertEquals(optionalRetailCustomer.get(), userService.getRetailCustomerById(userId)); - verify(retailCustomerRepository, times(1)).findById(userId); - } - + @Mock + private BCryptPasswordEncoder passwordEncoder; + + @Mock + private RoleRepository roleRepository; + + @Mock + private RetailCustomerRepository retailCustomerRepository; + + @InjectMocks + private UserServiceImpl userService; + + UserForm retailUserForm; + RetailCustomer retailCustomer; + Optional optionalRetailCustomer; + + private int userId; + private String userName; + private String password; + private String matchingPassword; + private String firstName; + private String lastName; + private String email; + private String mobile; + private String street; + private String postcode; + private String city; + + String passwordEncoded; + + private String roleNameCustomer; + private String roleNameRetailCustomer; + private Role roleCustomer; + private Role roleRetailCustomer; + Collection retailCustomerRoles; + + @Before + public void initObjects() { + initUserDetails(); + initPasswordEncoded(); + initRetailUserForm(); + initRoles(); + } + + private void initUserDetails() { + userId = 1; + userName = "username"; + firstName = "firstname"; + lastName = "lastname"; + email = "email@example.com"; + mobile = "123456789"; + street = "street"; + postcode = "12-345"; + city = "city"; + } + + private void initPasswordEncoded() { + password = "password"; + matchingPassword = "password"; + passwordEncoded = "xxxx"; + } + + private void initRetailUserForm() { + retailUserForm = new UserForm(); + retailUserForm.setUserName(userName); + retailUserForm.setPassword(password); + retailUserForm.setMatchingPassword(matchingPassword); + retailUserForm.setFirstName(firstName); + retailUserForm.setLastName(lastName); + retailUserForm.setEmail(email); + retailUserForm.setMobile(mobile); + retailUserForm.setStreet(street); + retailUserForm.setPostcode(postcode); + retailUserForm.setCity(city); + retailUserForm.setId(userId); + } + + private void initRoles() { + roleNameCustomer = "ROLE_CUSTOMER"; + roleNameRetailCustomer = "ROLE_CUSTOMER_RETAIL"; + roleCustomer = new Role(roleNameCustomer); + roleRetailCustomer = new Role(roleNameRetailCustomer); + retailCustomerRoles = new HashSet<>(); + retailCustomerRoles.add(roleCustomer); + retailCustomerRoles.add(roleRetailCustomer); + } + + @Test + public void shouldSaveNewRetailCustomer() { + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(RetailCustomer.class); + userService.saveNewRetailCustomer(retailUserForm); + + verify(retailCustomerRepository, times(1)).save(argumentCaptor.capture()); + } + + @Test + public void shouldEncodePasswordWhenForNewRetailCustomer() { + when(passwordEncoder.encode(password)).thenReturn(passwordEncoded); + + verifyAndCaptureRetailCustomer(); + assertEquals(retailCustomer.getPassword(), passwordEncoded); + } + + @Test + public void userFormDataShouldMatchRetailCustomerObject() { + verifyAndCaptureRetailCustomer(); + assertRetailCustomerEqualsFormData(retailCustomer, retailUserForm); + } + + @Test + public void shouldAssignTwoRolesForRetailCustomer() { + mockRoleRepository(); + verifyAndCaptureRetailCustomer(); + assertEquals(retailCustomer.getRoles().size(), 2); + } + + @Test + public void shouldAssignCorrectRolesForRetailCustomer() { + mockRoleRepository(); + verifyAndCaptureRetailCustomer(); + assertTrue(retailCustomer.hasRole(roleNameRetailCustomer)); + assertTrue(retailCustomer.hasRole(roleNameCustomer)); + } + + @Test + public void shouldUpdateRetailCustomerProfileData() { + mockRetailCustomerToUpdate(); + verifyAndCaptureRetailCustomer(); + assertRetailCustomerEqualsFormData(retailCustomer, retailUserForm); + } + + @Test + public void shouldNotAffectUsernameAndPasswordAndRolesWhileRetailCustomerProfileUpdate() { + mockRetailCustomerToUpdate(); + String currentUsername = "username2"; + String currentPassword = "password2"; + retailCustomer.setUserName(currentUsername); + retailCustomer.setPassword(currentPassword); + retailCustomer.setRoles(retailCustomerRoles); + + verifyAndCaptureRetailCustomer(); + + assertEquals(retailCustomer.getUserName(), currentUsername); + assertEquals(retailCustomer.getPassword(), currentPassword); + assertEquals(retailCustomer.getRoles(), retailCustomerRoles); + } + + @Test + public void shouldFindRetailCustomerById() { + mockRetailCustomerToFind(); + assertEquals(optionalRetailCustomer.get(), userService.getRetailCustomerById(userId)); + verify(retailCustomerRepository, times(1)).findById(userId); + } + + private void verifyAndCaptureRetailCustomer() { + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(RetailCustomer.class); + userService.saveNewRetailCustomer(retailUserForm); + verify(retailCustomerRepository, times(1)).save(argumentCaptor.capture()); + retailCustomer = argumentCaptor.getValue(); + } + + private void mockRoleRepository() { + doReturn(roleRetailCustomer).when(roleRepository).findByName(roleNameRetailCustomer); + doReturn(roleCustomer).when(roleRepository).findByName(roleNameCustomer); + } + + private void mockRetailCustomerToUpdate() { + RetailCustomer customerToBeUpdated = new RetailCustomer(); + customerToBeUpdated.setId(userId); + doReturn(customerToBeUpdated).when(retailCustomerRepository).getOne(userId); + } + + private void mockRetailCustomerToFind() { + retailCustomer = new RetailCustomer(); + retailCustomer.setId(userId); + retailCustomer.setUserName(userName); + optionalRetailCustomer = Optional.of(retailCustomer); + when(retailCustomerRepository.findById(userId)).thenReturn(optionalRetailCustomer); + } + + private void assertRetailCustomerEqualsFormData(RetailCustomer retailCustomer, UserForm retailUserForm) { + assertEquals(retailCustomer.getUserName(), retailUserForm.getUserName()); + assertEquals(retailCustomer.getFirstName(), retailUserForm.getFirstName()); + assertEquals(retailCustomer.getLastName(), retailUserForm.getLastName()); + assertEquals(retailCustomer.getEmail(), retailUserForm.getEmail()); + assertEquals(retailCustomer.getMobile(), retailUserForm.getMobile()); + assertEquals(retailCustomer.getStreet(), retailUserForm.getStreet()); + assertEquals(retailCustomer.getCity(), retailUserForm.getCity()); + assertEquals(retailCustomer.getPostcode(), retailUserForm.getPostcode()); + } } - - diff --git a/src/test/java/com/example/slabiak/appointmentscheduler/ui/LoginPageIT.java b/src/test/java/com/example/slabiak/appointmentscheduler/ui/LoginPageIT.java index 93323e7..73ee712 100644 --- a/src/test/java/com/example/slabiak/appointmentscheduler/ui/LoginPageIT.java +++ b/src/test/java/com/example/slabiak/appointmentscheduler/ui/LoginPageIT.java @@ -63,41 +63,64 @@ public void shouldShowLoginPageAndSuccessfullyLoginToAdminAccountUsingAdminCrede public void shouldLoginAsRetailCustomerAndSuccessfullyBookNewAppointment() { RemoteWebDriver driver = chrome.getWebDriver(); String url = "http://host.testcontainers.internal:" + port + "/"; - driver.get(url); driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS); + loginAsRetailCustomer(driver); + navigateToNewAppointmentPage(driver); + selectAppointmentSlot(driver); + confirmAppointmentBooking(driver); + + // Validate the result + validateAppointmentResult(driver); + } + + private void loginAsRetailCustomer(RemoteWebDriver driver) { driver.findElementById("username").sendKeys("customer_r"); driver.findElementById("password").sendKeys("qwerty123"); driver.findElementByTagName("button").click(); + } + private void navigateToNewAppointmentPage(RemoteWebDriver driver) { driver.findElementByLinkText("Appointments").click(); driver.findElementByLinkText("New appointment").click(); + } + + private void selectAppointmentSlot(RemoteWebDriver driver) { driver.findElementByLinkText("Select").click(); driver.findElementByLinkText("Select").click(); - driver.findElementByXPath("//*[@id=\"calendar\"]/div[1]/div[2]/div/button[2]/span\n").click(); - boolean result = false; - int attempts = 0; - while (attempts < 3) { - try { - driver.findElementByXPath("//*[@id=\"calendar\"]/div[2]/div/div/table/tbody/tr[2]/td[1]").click(); - result = true; - break; - } catch (StaleElementReferenceException e) { - } - attempts++; - } + // Handling dynamic XPath, retrying in case of StaleElementReferenceException + boolean result = retryingFindClick(driver, "//*[@id=\"calendar\"]/div[1]/div[2]/div/button[2]/span"); + assertTrue(result); + } + private void confirmAppointmentBooking(RemoteWebDriver driver) { + // Handling dynamic XPath, retrying in case of StaleElementReferenceException + retryingFindClick(driver, "//*[@id=\"calendar\"]/div[2]/div/div/table/tbody/tr[2]/td[1]"); driver.findElementByXPath("/html/body/div[2]/div/div/table/tbody/tr[8]/td/form/button").click(); + } + private void validateAppointmentResult(RemoteWebDriver driver) { WebElement table = driver.findElement(By.id("appointments")); WebElement tableBody = table.findElement(By.tagName("tbody")); int rowCount = tableBody.findElements(By.tagName("tr")).size(); - assertTrue(result); assertEquals(1, rowCount); } + private boolean retryingFindClick(RemoteWebDriver driver, String xpath) { + int attempts = 0; + while (attempts < 3) { + try { + driver.findElementByXPath(xpath).click(); + return true; + } catch (StaleElementReferenceException e) { + attempts++; + } + } + return false; + } + public static class Initializer implements ApplicationContextInitializer { @Override public void initialize(ConfigurableApplicationContext applicationContext) {