Skip to content

Commit

Permalink
[#11236] Uninformative error message for incorrectly typed date input (
Browse files Browse the repository at this point in the history
…#11524)

Co-authored-by: Fergus Mok <fergusmok1@gmail.com>
  • Loading branch information
ziqing26 and FergusMok authored Apr 17, 2022
1 parent 87ae891 commit e4b5850
Show file tree
Hide file tree
Showing 19 changed files with 126 additions and 77 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package teammates.e2e.cases;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;

import org.testng.annotations.Test;

import teammates.common.datatransfer.NotificationStyle;
import teammates.common.datatransfer.NotificationTargetUser;
import teammates.common.datatransfer.attributes.NotificationAttributes;
import teammates.common.util.AppUrl;
import teammates.common.util.Const;
import teammates.common.util.TimeHelper;
import teammates.e2e.pageobjects.AdminNotificationsPage;

/**
Expand Down Expand Up @@ -40,10 +43,11 @@ public void testAll() {
verifyPresentInDatabase(notifications[1]);

______TS("add new notification");
int currentYear = LocalDate.now().getYear();
NotificationAttributes newNotification = NotificationAttributes
.builder("placeholder-notif-id")
.withStartTime(TimeHelper.parseInstant("2035-04-01T22:00:00Z"))
.withEndTime(TimeHelper.parseInstant("2035-04-30T20:00:00Z"))
.withStartTime(LocalDateTime.of(currentYear + 8, 1, 2, 12, 0).atZone(ZoneId.of("UTC")).toInstant())
.withEndTime(LocalDateTime.of(currentYear + 8, 1, 3, 12, 0).atZone(ZoneId.of("UTC")).toInstant())
.withStyle(NotificationStyle.SUCCESS)
.withTargetUser(NotificationTargetUser.GENERAL)
.withTitle("E2E test notification 1")
Expand All @@ -64,8 +68,8 @@ public void testAll() {
notificationsPage.verifyNotificationsTableRow(newNotification);

______TS("edit notification");
newNotification.setStartTime(TimeHelper.parseInstant("2025-05-09T12:00:00Z"));
newNotification.setEndTime(TimeHelper.parseInstant("2045-06-01T22:00:00Z"));
newNotification.setStartTime(LocalDateTime.of(currentYear + 7, 2, 2, 12, 0).atZone(ZoneId.of("UTC")).toInstant());
newNotification.setEndTime(LocalDateTime.of(currentYear + 7, 2, 3, 12, 0).atZone(ZoneId.of("UTC")).toInstant());
newNotification.setStyle(NotificationStyle.DANGER);
newNotification.setTargetUser(NotificationTargetUser.INSTRUCTOR);
newNotification.setTitle("Edited E2E test notification 1");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public void testAll() {

______TS("edit session details");
feedbackSession.setInstructions("<p><strong>new instructions</strong></p>");
feedbackSession.setStartTime(feedbackSession.getEndTime().minus(30, ChronoUnit.DAYS));
feedbackSession.setStartTime(feedbackSession.getStartTime().minus(30, ChronoUnit.DAYS));
feedbackSession.setEndTime(feedbackSession.getEndTime().plus(30, ChronoUnit.DAYS));
feedbackSession.setGracePeriodMinutes(30);
feedbackSession.setSessionVisibleFromTime(Const.TIME_REPRESENTS_FOLLOW_OPENING);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
Expand All @@ -16,7 +19,6 @@
import teammates.common.datatransfer.attributes.StudentAttributes;
import teammates.common.util.AppUrl;
import teammates.common.util.Const;
import teammates.common.util.TimeHelper;
import teammates.e2e.pageobjects.InstructorFeedbackSessionsPage;
import teammates.e2e.util.TestProperties;
import teammates.test.ThreadHelper;
Expand Down Expand Up @@ -49,11 +51,12 @@ protected void prepareTestData() {

openSession = testData.feedbackSessions.get("openSession");
closedSession = testData.feedbackSessions.get("closedSession");
int currentYear = LocalDate.now().getYear();
newSession = FeedbackSessionAttributes
.builder("New Session", course.getId())
.withCreatorEmail(instructor.getEmail())
.withStartTime(TimeHelper.parseInstant("2035-04-01T22:00:00Z"))
.withEndTime(TimeHelper.parseInstant("2035-04-30T20:00:00Z"))
.withStartTime(LocalDateTime.of(currentYear + 8, 1, 2, 12, 0).atZone(ZoneId.of("UTC")).toInstant())
.withEndTime(LocalDateTime.of(currentYear + 8, 1, 3, 12, 0).atZone(ZoneId.of("UTC")).toInstant())
.withSessionVisibleFromTime(Const.TIME_REPRESENTS_FOLLOW_OPENING)
.withResultsVisibleFromTime(Const.TIME_REPRESENTS_LATER)
.withGracePeriod(Duration.ZERO)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,15 +141,15 @@ private void setMessage(String message) {
}

private void setNotificationStartDateTime(Instant startInstant) {
setDateTime(startDateBox.findElement(By.tagName("input")), startTimeDropdown, startInstant);
setDateTime(startDateBox, startTimeDropdown, startInstant);
}

private void setNotificationEndDateTime(Instant endInstant) {
setDateTime(endDateBox.findElement(By.tagName("input")), endTimeDropdown, endInstant);
setDateTime(endDateBox, endTimeDropdown, endInstant);
}

private void setDateTime(WebElement dateBox, WebElement timeBox, Instant startInstant) {
fillTextBox(dateBox, getInputDateString(startInstant));
fillDatePicker(dateBox, startInstant, getTimezone());
selectDropdownOptionByText(timeBox.findElement(By.tagName("select")), getInputTimeString(startInstant));
}

Expand All @@ -168,10 +168,6 @@ private String getTimezone() {
return notificationsTimezone.getText().replace("All dates are displayed in ", "").replace(" time.", "");
}

private String getInputDateString(Instant instant) {
return getDisplayedDateTime(instant, getTimezone(), "EE, dd MMM, yyyy");
}

private String getInputTimeString(Instant instant) {
String timezone = getTimezone();
ZonedDateTime dateTime = instant.atZone(ZoneId.of(timezone));
Expand Down
30 changes: 30 additions & 0 deletions src/e2e/java/teammates/e2e/pageobjects/AppPage.java
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,25 @@ protected void fillTextBox(WebElement textBoxElement, String value) {
textBoxElement.sendKeys(Keys.TAB); // blur the element to receive events
}

protected void fillDatePicker(WebElement dateBox, Instant startInstant, String timeZone) {
WebElement buttonToOpenPicker = dateBox.findElement(By.tagName("button"));
click(buttonToOpenPicker);

WebElement datePicker = dateBox.findElement(By.tagName("ngb-datepicker"));
WebElement monthAndYearPicker = datePicker.findElement(By.tagName("ngb-datepicker-navigation-select"));
WebElement monthPicker = monthAndYearPicker.findElement(By.cssSelector("[title='Select month']"));
WebElement yearPicker = monthAndYearPicker.findElement(By.cssSelector("[title='Select year']"));
WebElement dayPicker = datePicker.findElement(By.cssSelector("ngb-datepicker-month"));

String year = getYearString(startInstant, timeZone);
String month = getMonthString(startInstant, timeZone);
String date = getFullDateString(startInstant, timeZone);

selectDropdownOptionByText(yearPicker, year);
selectDropdownOptionByText(monthPicker, month);
dayPicker.findElement(By.cssSelector(String.format("[aria-label='%s']", date))).click();
}

protected void fillFileBox(RemoteWebElement fileBoxElement, String fileName) {
if (fileName.isEmpty()) {
fileBoxElement.clear();
Expand Down Expand Up @@ -671,4 +690,15 @@ String getDisplayedDateTime(Instant instant, String timeZone, String pattern) {
return DateTimeFormatter.ofPattern(pattern).format(zonedDateTime);
}

private String getFullDateString(Instant instant, String timeZone) {
return getDisplayedDateTime(instant, timeZone, "EEEE, MMMM d, yyyy");
}

private String getYearString(Instant instant, String timeZone) {
return getDisplayedDateTime(instant, timeZone, "yyyy");
}

private String getMonthString(Instant instant, String timeZone) {
return getDisplayedDateTime(instant, timeZone, "MMM");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -100,17 +100,11 @@ public void setStudentName(String studentName) {
}

public void setLogsFromDateTime(Instant instant, String timeZone) {
setDateTime(logsFromDatepicker, logsFromTimepicker.findElement(By.className("form-control")),
instant, timeZone);
setDateTime(logsFromDatepicker, logsToTimepicker, instant, timeZone);
}

public void setLogsToDateTime(Instant instant, String timeZone) {
setDateTime(logsToDatepicker, logsToTimepicker.findElement(By.className("form-control")),
instant, timeZone);
}

private String getDateString(Instant instant, String timeZone) {
return getDisplayedDateTime(instant, timeZone, "EE, dd MMM, yyyy");
setDateTime(logsToDatepicker, logsToTimepicker, instant, timeZone);
}

private String getTimeString(Instant instant, String timeZone) {
Expand All @@ -122,8 +116,8 @@ private String getTimeString(Instant instant, String timeZone) {
}

private void setDateTime(WebElement dateBox, WebElement timeBox, Instant startInstant, String timeZone) {
fillTextBox(dateBox, getDateString(startInstant, timeZone));
fillDatePicker(dateBox, startInstant, timeZone);

selectDropdownOptionByText(timeBox, getTimeString(startInstant, timeZone));
selectDropdownOptionByText(timeBox.findElement(By.tagName("select")), getTimeString(startInstant, timeZone));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -880,25 +880,23 @@ private void setInstructions(String newInstructions) {
}

private void setSessionStartDateTime(Instant startInstant, String timeZone) {
setDateTime(startDateBox.findElement(By.tagName("input")), startTimeDropdown, startInstant, timeZone);
setDateTime(startDateBox, startTimeDropdown, startInstant, timeZone);
}

private void setSessionEndDateTime(Instant endInstant, String timeZone) {
setDateTime(endDateBox.findElement(By.tagName("input")), endTimeDropdown, endInstant, timeZone);
setDateTime(endDateBox, endTimeDropdown, endInstant, timeZone);
}

private void setVisibilityDateTime(Instant startInstant, String timeZone) {
setDateTime(sessionVisibilityDateBox.findElement(By.tagName("input")),
sessionVisibilityTimeDropdown, startInstant, timeZone);
setDateTime(sessionVisibilityDateBox, sessionVisibilityTimeDropdown, startInstant, timeZone);
}

private void setResponseDateTime(Instant endInstant, String timeZone) {
setDateTime(responseVisibilityDateBox.findElement(By.tagName("input")),
responseVisibilityTimeDropdown, endInstant, timeZone);
setDateTime(responseVisibilityDateBox, responseVisibilityTimeDropdown, endInstant, timeZone);
}

private void setDateTime(WebElement dateBox, WebElement timeBox, Instant startInstant, String timeZone) {
fillTextBox(dateBox, getDateString(startInstant, timeZone));
fillDatePicker(dateBox, startInstant, timeZone);

selectDropdownOptionByText(timeBox.findElement(By.tagName("select")), getTimeString(startInstant, timeZone));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -316,10 +316,6 @@ private String[] getSoftDeletedSessionDetails(FeedbackSessionAttributes session)
return details;
}

private String getDateString(Instant instant, String timeZone) {
return getDisplayedDateTime(instant, timeZone, "EE, dd MMM, yyyy");
}

private String getSimpleDateString(Instant instant, String timeZone) {
return getDisplayedDateTime(instant, timeZone, "dd MMM, yyyy");
}
Expand Down Expand Up @@ -349,27 +345,23 @@ private void setInstructions(String newInstructions) {
}

private void setSessionStartDateTime(Instant startInstant, String timeZone) {
setDateTime(startDateBox.findElement(By.tagName("input")),
startTimeDropdown, startInstant, timeZone);
setDateTime(startDateBox, startTimeDropdown, startInstant, timeZone);
}

private void setSessionEndDateTime(Instant endInstant, String timeZone) {
setDateTime(endDateBox.findElement(By.tagName("input")),
endTimeDropdown, endInstant, timeZone);
setDateTime(endDateBox, endTimeDropdown, endInstant, timeZone);
}

private void setVisibilityDateTime(Instant startInstant, String timeZone) {
setDateTime(sessionVisibilityDateBox.findElement(By.tagName("input")),
sessionVisibilityTimeDropdown, startInstant, timeZone);
setDateTime(sessionVisibilityDateBox, sessionVisibilityTimeDropdown, startInstant, timeZone);
}

private void setResponseDateTime(Instant endInstant, String timeZone) {
setDateTime(responseVisibilityDateBox.findElement(By.tagName("input")),
responseVisibilityTimeDropdown, endInstant, timeZone);
setDateTime(responseVisibilityDateBox, responseVisibilityTimeDropdown, endInstant, timeZone);
}

private void setDateTime(WebElement dateBox, WebElement timeBox, Instant startInstant, String timeZone) {
fillTextBox(dateBox, getDateString(startInstant, timeZone));
fillDatePicker(dateBox, startInstant, timeZone);

selectDropdownOptionByText(timeBox.findElement(By.tagName("select")), getTimeString(startInstant, timeZone));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,7 @@ public void extendDeadlineToOneDayAway(FeedbackSessionAttributes session, boolea

// set date
WebElement datePicker = browser.driver.findElement(By.id("submission-end-date"));
WebElement dateTextBox = datePicker.findElement(By.tagName("input"));
fillTextBox(dateTextBox, getDateString(extendedDeadline, session.getTimeZone()));
fillDatePicker(datePicker, extendedDeadline, session.getTimeZone());

browser.driver.findElement(By.className("modal-btn-ok")).click();
confirmChangesToDeadlineExtensions(notifyUsers);
Expand All @@ -236,10 +235,6 @@ private void confirmChangesToDeadlineExtensions(boolean notifyUsers) {
waitForPageToLoad(true);
}

private String getDateString(Instant instant, String timezone) {
return TimeHelper.formatInstant(instant, timezone, "yyyy-MM-dd");
}

private String getTimeString(Instant instant, String timezone) {
return TimeHelper.formatInstant(instant, timezone, "HH:mm") + "H";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,17 +133,17 @@ public void validate() throws InvalidHttpRequestBodyException {
assertTrue(sessionVisibleSetting != null, "sessionVisibleSetting cannot be null");
if (sessionVisibleSetting == SessionVisibleSetting.CUSTOM) {
assertTrue(customSessionVisibleTimestamp != null,
"session visible timestamp should not be null");
"Session visible timestamp should not be null");
assertTrue(customSessionVisibleTimestamp > 0L,
"session visible timestamp should be more than zero");
"Session visible timestamp should be more than zero");
}

assertTrue(responseVisibleSetting != null, "responseVisibleSetting cannot be null");
if (responseVisibleSetting == ResponseVisibleSetting.CUSTOM) {
assertTrue(customResponseVisibleTimestamp != null,
"response visible timestamp should not be null");
"Response visible timestamp should not be null");
assertTrue(customResponseVisibleTimestamp > 0L,
"response visible timestamp should be more than zero");
"Response visible timestamp should be more than zero");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
Today
</button>
</ng-template>
<input type="text" class="form-control" ngbDatepicker
<input type="text" class="form-control" ngbDatepicker readonly
[ngModel]="date" (ngModelChange)="changeDate($event)"
[maxDate]="maxDate" [minDate]="minDate" #timeDp="ngbDatepicker" [disabled]="disabled" [footerTemplate]="footer"/>
<div class="input-group-append" *ngIf="!disabled">
Expand Down
10 changes: 10 additions & 0 deletions src/web/app/components/datepicker/datepicker.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,13 @@
cursor: pointer;
outline: none;
}

.form-control {
&[readonly] {
background-color: transparent;
}

&:disabled {
background-color: #E9ECEF;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ exports[`AdminNotificationsPageComponent should snap when notification edit form
<input
class="form-control ng-untouched ng-pristine ng-valid"
ngbdatepicker=""
readonly=""
type="text"
/>
<div
Expand Down Expand Up @@ -485,6 +486,7 @@ exports[`AdminNotificationsPageComponent should snap when notification edit form
<input
class="form-control ng-untouched ng-pristine ng-valid"
ngbdatepicker=""
readonly=""
type="text"
/>
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ exports[`NotificationEditFormComponent should snap with default view 1`] = `
<input
class="form-control ng-untouched ng-pristine ng-valid"
ngbdatepicker=""
readonly=""
type="text"
/>
<div
Expand Down Expand Up @@ -458,6 +459,7 @@ exports[`NotificationEditFormComponent should snap with default view 1`] = `
<input
class="form-control ng-untouched ng-pristine ng-valid"
ngbdatepicker=""
readonly=""
type="text"
/>
<div
Expand Down Expand Up @@ -913,6 +915,7 @@ exports[`NotificationEditFormComponent should snap with notification 1`] = `
<input
class="form-control ng-untouched ng-pristine ng-invalid"
ngbdatepicker=""
readonly=""
type="text"
/>
<div
Expand Down Expand Up @@ -1100,6 +1103,7 @@ exports[`NotificationEditFormComponent should snap with notification 1`] = `
<input
class="form-control ng-untouched ng-pristine ng-invalid"
ngbdatepicker=""
readonly=""
type="text"
/>
<div
Expand Down Expand Up @@ -1572,6 +1576,7 @@ exports[`NotificationEditFormComponent should snap with notification that has be
<input
class="form-control ng-untouched ng-pristine ng-invalid"
ngbdatepicker=""
readonly=""
type="text"
/>
<div
Expand Down Expand Up @@ -1759,6 +1764,7 @@ exports[`NotificationEditFormComponent should snap with notification that has be
<input
class="form-control ng-untouched ng-pristine ng-invalid"
ngbdatepicker=""
readonly=""
type="text"
/>
<div
Expand Down
Loading

0 comments on commit e4b5850

Please sign in to comment.