From 9d7969c98d859df726e9bb181d5aa5332904f95b Mon Sep 17 00:00:00 2001 From: hg <none@none> Date: Tue, 15 Nov 2016 20:10:45 +0100 Subject: [PATCH] OO-2019: selenium test base on feedback of sscheiwiler --- .../calendar/ui/CalendarEntryForm.java | 2 +- .../calendar/ui/ConfirmDeleteController.java | 1 + .../config/ui/CourseOptionsController.java | 2 + .../org/olat/selenium/BusinessGroupTest.java | 4 +- .../java/org/olat/selenium/CourseTest.java | 91 +++++++++++++++++-- .../olat/selenium/page/core/CalendarPage.java | 31 +++++-- .../page/course/CourseOptionsPage.java | 63 +++++++++++++ .../page/course/CoursePageFragment.java | 11 +++ .../selenium/page/graphene/OOGraphene.java | 12 +++ 9 files changed, 198 insertions(+), 19 deletions(-) create mode 100644 src/test/java/org/olat/selenium/page/course/CourseOptionsPage.java diff --git a/src/main/java/org/olat/commons/calendar/ui/CalendarEntryForm.java b/src/main/java/org/olat/commons/calendar/ui/CalendarEntryForm.java index 465722a2c30..b949d274962 100644 --- a/src/main/java/org/olat/commons/calendar/ui/CalendarEntryForm.java +++ b/src/main/java/org/olat/commons/calendar/ui/CalendarEntryForm.java @@ -381,7 +381,7 @@ public class CalendarEntryForm extends FormBasicController { classification = uifactory.addRadiosVertical("classification", "cal.form.class", formLayout, classKeys, classValues); classification.setHelpUrlForManualPage("Calendar#_visibility"); - classification.setHelpTextKey("cal.form.class.hover", null); + //classification.setHelpTextKey("cal.form.class.hover", null); classification.setEnabled(!CalendarManagedFlag.isManaged(event, CalendarManagedFlag.classification)); switch (event.getClassification()) { case KalendarEvent.CLASS_PRIVATE: classification.select("0", true); break; diff --git a/src/main/java/org/olat/commons/calendar/ui/ConfirmDeleteController.java b/src/main/java/org/olat/commons/calendar/ui/ConfirmDeleteController.java index 903047cf534..4696602d8b0 100644 --- a/src/main/java/org/olat/commons/calendar/ui/ConfirmDeleteController.java +++ b/src/main/java/org/olat/commons/calendar/ui/ConfirmDeleteController.java @@ -62,6 +62,7 @@ public class ConfirmDeleteController extends BasicController { deleteAllButton.setElementCssClass("o_sel_cal_delete_all"); } else { deleteFutureButton = LinkFactory.createButton("delete.future", mainVC, this); + deleteFutureButton.setElementCssClass("o_sel_cal_delete_future_events"); } deleteOneButton = LinkFactory.createButton("delete.one", mainVC, this); deleteOneButton.setElementCssClass("o_sel_cal_delete_one"); diff --git a/src/main/java/org/olat/course/config/ui/CourseOptionsController.java b/src/main/java/org/olat/course/config/ui/CourseOptionsController.java index e8ed5f8a032..76ad1da8f71 100644 --- a/src/main/java/org/olat/course/config/ui/CourseOptionsController.java +++ b/src/main/java/org/olat/course/config/ui/CourseOptionsController.java @@ -201,6 +201,7 @@ public class CourseOptionsController extends FormBasicController { boolean calendarEnabled = courseConfig.isCalendarEnabled(); boolean managedCal = RepositoryEntryManagedFlag.isManaged(entry, RepositoryEntryManagedFlag.calendar); calendarEl = uifactory.addCheckboxesHorizontal("calIsOn", "chkbx.calendar.onoff", calendarCont, onKeys, onValues); + calendarEl.setElementCssClass("o_sel_course_options_calendar"); calendarEl.addActionListener(FormEvent.ONCHANGE); calendarEl.select("xx", calendarEnabled); calendarEl.setEnabled(editable && !managedCal); @@ -280,6 +281,7 @@ public class CourseOptionsController extends FormBasicController { saveCont.setRootForm(mainForm); formLayout.add(saveCont); saveButton = uifactory.addFormLink("save", saveCont, Link.BUTTON); + saveButton.setElementCssClass("o_sel_course_options_save"); saveButton.setPrimary(true); } } diff --git a/src/test/java/org/olat/selenium/BusinessGroupTest.java b/src/test/java/org/olat/selenium/BusinessGroupTest.java index d3066be42a8..bde32fff1b8 100644 --- a/src/test/java/org/olat/selenium/BusinessGroupTest.java +++ b/src/test/java/org/olat/selenium/BusinessGroupTest.java @@ -671,7 +671,7 @@ public class BusinessGroupTest { .edit() .setDescription("Special", null, null) .save() - .configureModifyOneOccurence() + .confirmModifyOneOccurence() .assertOnEvents("Special", 1) .assertOnEvents("Recurring", 3); @@ -681,7 +681,7 @@ public class BusinessGroupTest { .edit() .setBeginEnd(11, 12).assertOnEvents("Special", 1) .save() - .configureModifyAllOccurences() + .confirmModifyAllOccurences() .assertOnEventsAt("Recurring", 3, 11); } diff --git a/src/test/java/org/olat/selenium/CourseTest.java b/src/test/java/org/olat/selenium/CourseTest.java index 0d287797958..f11e8b29dfe 100644 --- a/src/test/java/org/olat/selenium/CourseTest.java +++ b/src/test/java/org/olat/selenium/CourseTest.java @@ -1185,7 +1185,7 @@ public class CourseTest { navBar.openCourse(courseTitle); String calendarNodeTitle = "iCal-1"; - //create a course element of type CP with the CP that we create above + //create a course element of type calendar CourseEditorPageFragment courseEditor = CoursePageFragment.getCourse(browser) .edit(); courseEditor @@ -1197,7 +1197,7 @@ public class CourseTest { .publish() .quickPublish(); - //open the course and see the CP + //open the course and see the calendar CoursePageFragment course = courseEditor .clickToolbarBack(); course @@ -1218,7 +1218,7 @@ public class CourseTest { .setAllDay(false) .setBeginEnd(13, 15) .save() - .configureModifyOneOccurence(); + .confirmModifyOneOccurence(); // check calendar @@ -1231,7 +1231,7 @@ public class CourseTest { .edit() .setDescription("Eventoki", null, null) .save() - .configureModifyAllOccurences(); + .confirmModifyAllOccurences(); // check calendar .assertOnEvents("Eventoki", 3) @@ -1242,7 +1242,7 @@ public class CourseTest { .openDetailsOccurence("Eventoki", 10) .edit() .delete() - .configureDeleteOneOccurence(); + .confirmDeleteOneOccurence(); // check calendar .assertOnEvents("Eventoki", 2) @@ -1253,13 +1253,90 @@ public class CourseTest { .openDetailsOccurence("Eventoki", 3) .edit() .delete() - .configureDeleteAllOccurences(); + .confirmDeleteAllOccurences(); OOGraphene.waitingALittleBit(); calendar .assertZeroEvent(); } - + + /** + * This is a variant of the test above based on the + * feedback of our beta-testerin. + * + * @param loginPage + * @throws IOException + * @throws URISyntaxException + */ + @Test + @RunAsClient + public void courseWithCalendar_alt(@InitialPage LoginPage loginPage) + throws IOException, URISyntaxException { + + UserVO author = new UserRestClient(deploymentUrl).createAuthor(); + loginPage.loginAs(author.getLogin(), author.getPassword()); + + //create a course + String courseTitle = "Course-iCal-" + UUID.randomUUID(); + navBar + .openAuthoringEnvironment() + .createCourse(courseTitle) + .clickToolbarBack(); + + navBar.openCourse(courseTitle); + + // activate the calendar options + CoursePageFragment course = CoursePageFragment.getCourse(browser); + course + .options() + .calendar(Boolean.TRUE) + .save() + .clickToolbarBack(); + + String calendarNodeTitle = "iCal-2"; + //create a course element of type calendar + CourseEditorPageFragment courseEditor = CoursePageFragment.getCourse(browser) + .edit(); + courseEditor + .createNode("cal") + .nodeTitle(calendarNodeTitle); + + //publish the course + course = courseEditor + .autoPublish(); + //open the course and see the CP + course + .clickTree() + .selectWithTitle(calendarNodeTitle); + + // create a recurring event + CalendarPage calendar = new CalendarPage(browser); + calendar + .addEvent(2) + .setDescription("Repeat", "Loop", "Foreach") + .setAllDay(false) + .setBeginEnd(14, 18) + .setRecurringEvent(KalendarEvent.WEEKLY, 28) + .save() + .assertOnEvents("Repeat", 4); + + //pick an occurence which is not the first and modify it + calendar + .openDetailsOccurence("Repeat", 16) + .edit() + .setBeginEnd(15, 18) + .save() + .confirmModifyAllOccurences() + .assertOnEventsAt("Repeat", 4, 15); + + // delete futur event of the same event as above + calendar + .openDetailsOccurence("Repeat", 16) + .edit() + .delete() + .confirmDeleteFuturOccurences() + .assertOnEventsAt("Repeat", 2, 15); + } /** * An author creates a course, make it visible for diff --git a/src/test/java/org/olat/selenium/page/core/CalendarPage.java b/src/test/java/org/olat/selenium/page/core/CalendarPage.java index ece5f75066b..f2a6b9c90a0 100644 --- a/src/test/java/org/olat/selenium/page/core/CalendarPage.java +++ b/src/test/java/org/olat/selenium/page/core/CalendarPage.java @@ -146,11 +146,13 @@ public class CalendarPage { By recurrenceBy = By.id("o_fiocal_form_recurrence_SELBOX"); WebElement recurrenceEl = browser.findElement(recurrenceBy); new Select(recurrenceEl).selectByValue(recur); + OOGraphene.waitBusy(browser); - //LocalDate date = LocalDate.now().withDayOfMonth(day); - By untilBy = By.cssSelector("fieldset.o_sel_cal_entry_form div.o_sel_cal_until input[type='text']"); - OOGraphene.waitElement(untilBy, 5, browser); - browser.findElement(untilBy).click(); + //By untilBy = By.cssSelector("fieldset.o_sel_cal_entry_form div.o_sel_cal_until input[type='text']"); + By untilAltBy = By.cssSelector("fieldset.o_sel_cal_entry_form div.o_sel_cal_until span.input-group-addon i"); + OOGraphene.waitElement(untilAltBy, 5, browser); + browser.findElement(untilAltBy).click(); + OOGraphene.waitGui(browser); selectDayInDatePicker(day); return this; @@ -171,12 +173,15 @@ public class CalendarPage { public CalendarPage save() { By saveBy = By.cssSelector("fieldset.o_sel_cal_entry_form button.btn.btn-primary"); OOGraphene.waitElement(saveBy, 5, browser); - browser.findElement(saveBy).click(); + + WebElement saveEl = browser.findElement(saveBy); + OOGraphene.moveTo(saveEl, browser) + .click(); OOGraphene.waitBusy(browser); return this; } - public CalendarPage configureModifyOneOccurence() { + public CalendarPage confirmModifyOneOccurence() { By saveOneBy = By.cssSelector("div.modal-dialog a.o_sel_cal_update_one"); OOGraphene.waitElement(saveOneBy, 5, browser); browser.findElement(saveOneBy).click(); @@ -184,7 +189,7 @@ public class CalendarPage { return this; } - public CalendarPage configureModifyAllOccurences() { + public CalendarPage confirmModifyAllOccurences() { By saveAllBy = By.cssSelector("div.modal-dialog a.o_sel_cal_update_all"); OOGraphene.waitElement(saveAllBy, 5, browser); browser.findElement(saveAllBy).click(); @@ -200,7 +205,7 @@ public class CalendarPage { return this; } - public CalendarPage configureDeleteOneOccurence() { + public CalendarPage confirmDeleteOneOccurence() { By deleteOneBy = By.cssSelector("div.modal-dialog a.o_sel_cal_delete_one"); OOGraphene.waitElement(deleteOneBy, 5, browser); browser.findElement(deleteOneBy).click(); @@ -208,7 +213,15 @@ public class CalendarPage { return this; } - public CalendarPage configureDeleteAllOccurences() { + public CalendarPage confirmDeleteFuturOccurences() { + By deleteFutureBy = By.cssSelector("div.modal-dialog a.o_sel_cal_delete_future_events"); + OOGraphene.waitElement(deleteFutureBy, 5, browser); + browser.findElement(deleteFutureBy).click(); + OOGraphene.waitBusy(browser); + return this; + } + + public CalendarPage confirmDeleteAllOccurences() { By deleteAllBy = By.cssSelector("div.modal-dialog a.o_sel_cal_delete_all"); OOGraphene.waitElement(deleteAllBy, 5, browser); browser.findElement(deleteAllBy).click(); diff --git a/src/test/java/org/olat/selenium/page/course/CourseOptionsPage.java b/src/test/java/org/olat/selenium/page/course/CourseOptionsPage.java new file mode 100644 index 00000000000..222fb307ee6 --- /dev/null +++ b/src/test/java/org/olat/selenium/page/course/CourseOptionsPage.java @@ -0,0 +1,63 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.selenium.page.course; + +import org.olat.selenium.page.NavigationPage; +import org.olat.selenium.page.graphene.OOGraphene; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; + +/** + * + * Initial date: 15 nov. 2016<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class CourseOptionsPage { + + private WebDriver browser; + + public CourseOptionsPage(WebDriver browser) { + this.browser = browser; + } + + public CourseOptionsPage calendar(Boolean enable) { + By calendarBy = By.cssSelector(".o_sel_course_options_calendar input[type='checkbox']"); + WebElement calendarEl = browser.findElement(calendarBy); + OOGraphene.check(calendarEl, enable); + OOGraphene.waitBusy(browser); + return this; + } + + public CourseOptionsPage save() { + By saveBy = By.cssSelector("a.o_sel_course_options_save"); + browser.findElement(saveBy).click(); + OOGraphene.waitBusy(browser); + return this; + } + + public CoursePageFragment clickToolbarBack() { + browser.findElement(NavigationPage.toolbarBackBy).click(); + OOGraphene.waitBusy(browser); + return CoursePageFragment.getCourse(browser); + } + +} diff --git a/src/test/java/org/olat/selenium/page/course/CoursePageFragment.java b/src/test/java/org/olat/selenium/page/course/CoursePageFragment.java index 48f1a20b06c..6527837682a 100644 --- a/src/test/java/org/olat/selenium/page/course/CoursePageFragment.java +++ b/src/test/java/org/olat/selenium/page/course/CoursePageFragment.java @@ -171,6 +171,17 @@ public class CoursePageFragment { return new RemindersPage(browser); } + public CourseOptionsPage options() { + if(!browser.findElement(settingsMenu).isDisplayed()) { + openSettingsMenu(); + } + + By reminderBy = By.cssSelector("a.o_sel_course_options"); + browser.findElement(reminderBy).click(); + OOGraphene.waitBusy(browser); + return new CourseOptionsPage(browser); + } + /** * Click the editor link in the tools drop-down * @return diff --git a/src/test/java/org/olat/selenium/page/graphene/OOGraphene.java b/src/test/java/org/olat/selenium/page/graphene/OOGraphene.java index a1925c4e60c..47343a3fee7 100644 --- a/src/test/java/org/olat/selenium/page/graphene/OOGraphene.java +++ b/src/test/java/org/olat/selenium/page/graphene/OOGraphene.java @@ -35,6 +35,7 @@ import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.TimeoutException; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; /** * @@ -87,6 +88,17 @@ public class OOGraphene { Graphene.waitModel(browser).pollingEvery(poolingDuration, TimeUnit.MILLISECONDS).until().element(element).is().visible(); } + public static void waitGui(WebDriver browser) { + Graphene.waitGui(browser); + } + + public static WebElement moveTo(WebElement element, WebDriver browser) { + Actions actions = new Actions(browser); + actions.moveToElement(element); + actions.perform(); + return element; + } + // top.tinymce.get('o_fi1000000416').setContent('<p>Hacked</p>'); // <div id="o_fi1000000416_diw" class="o_richtext_mce"> <iframe id="o_fi1000000416_ifr"> public static final void tinymce(String content, WebDriver browser) { -- GitLab