From afba6d6bfa58bb98221527665051e620d1ce3bcb Mon Sep 17 00:00:00 2001 From: srosse <none@none> Date: Thu, 23 Jul 2015 21:18:04 +0200 Subject: [PATCH] no-jira: selenium test for concurrent use of the forum in a course --- .../org/olat/modules/fo/ForumController.java | 2 + .../modules/fo/MessageEditController.java | 3 + .../java/org/olat/selenium/CourseTest.java | 129 ++++++++++++++++++ .../olat/selenium/page/forum/ForumPage.java | 62 +++++++-- 4 files changed, 186 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/olat/modules/fo/ForumController.java b/src/main/java/org/olat/modules/fo/ForumController.java index b64cf4208e2..436719b2a18 100644 --- a/src/main/java/org/olat/modules/fo/ForumController.java +++ b/src/main/java/org/olat/modules/fo/ForumController.java @@ -1276,8 +1276,10 @@ public class ForumController extends BasicController implements GenericEventList edLink.setIconLeftCSS("o_icon o_icon-fw o_icon_edit"); Link qtLink = LinkFactory.createCustomLink("qt_"+msgCount, "qt_"+msgCount, "msg.quote", Link.BUTTON_SMALL, vcThreadView, this); + qtLink.setElementCssClass("o_sel_forum_reply_quoted"); qtLink.setIconLeftCSS("o_icon o_icon-fw o_icon_reply_with_quote"); Link rpLink = LinkFactory.createCustomLink("rp_"+msgCount, "rp_"+msgCount, "msg.reply", Link.BUTTON_SMALL, vcThreadView, this); + rpLink.setElementCssClass("o_sel_forum_reply"); rpLink.setIconLeftCSS("o_icon o_icon-fw o_icon_reply"); Link splitLink = LinkFactory.createCustomLink("split_"+msgCount, "split_"+msgCount, "msg.split", Link.LINK, vcThreadView, this); diff --git a/src/main/java/org/olat/modules/fo/MessageEditController.java b/src/main/java/org/olat/modules/fo/MessageEditController.java index f87c9ab80c5..e057a0fe33e 100644 --- a/src/main/java/org/olat/modules/fo/MessageEditController.java +++ b/src/main/java/org/olat/modules/fo/MessageEditController.java @@ -146,7 +146,10 @@ public class MessageEditController extends FormBasicController { */ @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { + formLayout.setElementCssClass("o_sel_forum_message_form"); + msgTitle = uifactory.addTextElement("msgTitle", "msg.title", 100, message.getTitle(), formLayout); + msgTitle.setElementCssClass("o_sel_forum_message_title"); msgTitle.setMandatory(true); msgTitle.setNotEmptyCheck("error.field.not.empty"); msgBody = uifactory.addRichTextElementForStringData("msgBody", "msg.body", message.getBody(), 15, -1, true, null, null, diff --git a/src/test/java/org/olat/selenium/CourseTest.java b/src/test/java/org/olat/selenium/CourseTest.java index 3f8d2719188..3e69beda06b 100644 --- a/src/test/java/org/olat/selenium/CourseTest.java +++ b/src/test/java/org/olat/selenium/CourseTest.java @@ -43,6 +43,7 @@ import org.olat.selenium.page.Administrator; import org.olat.selenium.page.LoginPage; import org.olat.selenium.page.NavigationPage; import org.olat.selenium.page.Participant; +import org.olat.selenium.page.Student; import org.olat.selenium.page.User; import org.olat.selenium.page.core.BookingPage; import org.olat.selenium.page.core.MenuTreePageFragment; @@ -53,6 +54,7 @@ import org.olat.selenium.page.course.InfoMessageCEPage; import org.olat.selenium.page.course.PublisherPageFragment; import org.olat.selenium.page.course.RemindersPage; import org.olat.selenium.page.course.PublisherPageFragment.Access; +import org.olat.selenium.page.forum.ForumPage; import org.olat.selenium.page.graphene.OOGraphene; import org.olat.selenium.page.repository.AuthoringEnvPage; import org.olat.selenium.page.repository.FeedPage; @@ -1128,4 +1130,131 @@ public class CourseTest { ryomouCourse .assertOnTitle(infoTitle); } + + /** + * An author creates a course with a forum, publish it, open a new thread. + * A first user come to see the thread. A second come via the peekview. + * The three make a reply at the same time. And they check that they see + * the replies, and the ones of the others. + * + * @param loginPage + * @param kanuBrowser + * @param reiBrowser + * @throws IOException + * @throws URISyntaxException + */ + @Test + @RunAsClient + public void concurrentForum(@InitialPage LoginPage loginPage, + @Drone @Participant WebDriver kanuBrowser, + @Drone @Student WebDriver reiBrowser) + throws IOException, URISyntaxException { + UserVO author = new UserRestClient(deploymentUrl).createAuthor(); + UserVO kanu = new UserRestClient(deploymentUrl).createRandomUser("Kanu"); + UserVO rei = new UserRestClient(deploymentUrl).createRandomUser("Rei"); + loginPage.loginAs(author.getLogin(), author.getPassword()); + + //create a course + String courseTitle = "Course FO " + UUID.randomUUID(); + navBar + .openAuthoringEnvironment() + .createCourse(courseTitle) + .clickToolbarBack(); + + //go the authoring environment to create a forum + String foTitle = "FO - " + UUID.randomUUID(); + CourseEditorPageFragment courseEditor = CoursePageFragment.getCourse(browser) + .edit(); + courseEditor + .createNode("fo") + .nodeTitle(foTitle) + //publish the course + .publish() + .quickPublish(Access.users); + + //go to the forum + courseEditor + .clickToolbarBack() + .clickTree() + .selectWithTitle(foTitle.substring(0, 20)); + + ForumPage authorForum = ForumPage + .getCourseForumPage(browser); + authorForum + .createThread("The best anime ever", "What is the best anime ever?"); + + //First user go to the course + LoginPage kanuLoginPage = LoginPage.getLoginPage(kanuBrowser, deploymentUrl); + kanuLoginPage + .loginAs(kanu.getLogin(), kanu.getPassword()) + .resume(); + + NavigationPage kanuNavBar = new NavigationPage(kanuBrowser); + kanuNavBar + .openMyCourses() + .openSearch() + .extendedSearch(courseTitle) + .select(courseTitle) + .start(); + + //go to the forum + new CoursePageFragment(kanuBrowser) + .clickTree() + .selectWithTitle(foTitle.substring(0, 20)); + + ForumPage kanuForum = ForumPage + .getCourseForumPage(kanuBrowser) + .openThread("The best anime ever"); + + + //First user go to the course + LoginPage reiLoginPage = LoginPage.getLoginPage(reiBrowser, deploymentUrl); + reiLoginPage + .loginAs(rei) + .resume(); + + NavigationPage reiNavBar = new NavigationPage(reiBrowser); + reiNavBar + .openMyCourses() + .openSearch() + .extendedSearch(courseTitle) + .select(courseTitle) + .start(); + //select the thread in peekview + ForumPage reiForum = new ForumPage(reiBrowser) + .openThreadInPeekview("The best anime ever"); + + //concurrent reply + String kanuReply = "Ikki Touzen"; + String reiReply = "Neon Genesis Evangelion"; + String authorReply = "Lain, serial experiment"; + + authorForum + .replyToMessageNoWait("The best anime ever", null, authorReply); + reiForum + .replyToMessageNoWait("The best anime ever", null, reiReply); + kanuForum + .replyToMessageNoWait("The best anime ever", null, kanuReply); + + //wait the responses + OOGraphene.waitBusy(browser); + OOGraphene.waitBusy(kanuBrowser); + OOGraphene.waitBusy(reiBrowser); + + //check own responses + authorForum.assertMessageBody(authorReply); + kanuForum.assertMessageBody(kanuReply); + reiForum.assertMessageBody(reiReply); + + //check others responses + authorForum + .flatView() + .waitMessageBody(kanuReply); + reiForum + .flatView() + .waitMessageBody(kanuReply); + kanuForum + .flatView() + .waitMessageBody(reiReply); + } } diff --git a/src/test/java/org/olat/selenium/page/forum/ForumPage.java b/src/test/java/org/olat/selenium/page/forum/ForumPage.java index 19870733aa5..d99e830b9a7 100644 --- a/src/test/java/org/olat/selenium/page/forum/ForumPage.java +++ b/src/test/java/org/olat/selenium/page/forum/ForumPage.java @@ -21,8 +21,6 @@ package org.olat.selenium.page.forum; import java.util.List; -import org.jboss.arquillian.drone.api.annotation.Drone; -import org.jboss.arquillian.graphene.Graphene; import org.junit.Assert; import org.olat.selenium.page.graphene.OOGraphene; import org.olat.selenium.page.portfolio.ArtefactWizardPage; @@ -39,14 +37,9 @@ import org.openqa.selenium.WebElement; * */ public class ForumPage { - - @Drone + private WebDriver browser; - public ForumPage() { - // - } - public ForumPage(WebDriver browser) { this.browser = browser; } @@ -64,14 +57,14 @@ public class ForumPage { By mainBy = By.cssSelector("div.o_course_run"); WebElement main = browser.findElement(mainBy); - return Graphene.createPageFragment(ForumPage.class, main); + Assert.assertTrue(main.isDisplayed()); + return new ForumPage(browser); } public static ForumPage getGroupForumPage(WebDriver browser) { By forumBy = By.cssSelector("div.o_forum"); List<WebElement> forumEl = browser.findElements(forumBy); Assert.assertFalse(forumEl.isEmpty()); - return new ForumPage(browser); } @@ -103,6 +96,27 @@ public class ForumPage { return this; } + public ForumPage openThread(String title) { + By threadBy = By.xpath("//table[contains(@class,'o_table')]//tr//a[span[text()='" + title + "']]"); + browser.findElement(threadBy).click(); + OOGraphene.waitBusy(browser); + return this; + } + + public ForumPage openThreadInPeekview(String title) { + By threadBy = By.xpath("//div[contains(@class,'o_forum_peekview_message')]//a[span[text()='" + title + "']]"); + browser.findElement(threadBy).click(); + OOGraphene.waitBusy(browser); + return this; + } + + public ForumPage flatView() { + By flatBy = By.cssSelector("input[value='flat'][type='radio']"); + browser.findElement(flatBy).click(); + OOGraphene.waitBusy(browser); + return this; + } + public ForumPage assertMessageBody(String text) { By messageBodyBy = By.className("o_forum_message_body"); List<WebElement> messages = browser.findElements(messageBodyBy); @@ -116,6 +130,34 @@ public class ForumPage { return this; } + public ForumPage waitMessageBody(String text) { + By messageBy = By.xpath("//div[contains(@class,'o_forum_message_body')][//p[contains(text(),'" + text + "')]]"); + OOGraphene.waitElement(messageBy, 10, browser); + return this; + } + + public ForumPage replyToMessage(String reference, String title, String reply) { + replyToMessageNoWait(reference, title, reply); + OOGraphene.waitBusy(browser); + return this; + } + + public ForumPage replyToMessageNoWait(String reference, String title, String reply) { + By replyBy = By.xpath("//div[contains(@class,'o_forum_message')][//h4[contains(text(),'" + reference + "')]]//a[contains(@class,'o_sel_forum_reply')]"); + browser.findElement(replyBy).click(); + OOGraphene.waitBusy(browser); + + if(title != null) { + By titleBy = By.cssSelector(".o_sel_forum_message_title input[type='text']"); + browser.findElement(titleBy).sendKeys(title); + } + OOGraphene.tinymce(reply, browser); + + By saveBy = By.cssSelector("fieldset.o_sel_forum_message_form button.btn-primary"); + browser.findElement(saveBy).click(); + return this; + } + /** * Add the thread to my artefacts * -- GitLab