Skip to content
Snippets Groups Projects
Commit 27d76e04 authored by srosse's avatar srosse
Browse files

Merge OpenOLAT default branch to OpenOLAT qti with 177baf0177c3d22c247d8e3282f073a0e5911013

parents 038f05e1 cc15c88f
No related branches found
No related tags found
No related merge requests found
Showing
with 286 additions and 32 deletions
......@@ -2,11 +2,11 @@
admin.menu.title=Forum
admin.menu.title.alt=Konfiguration Forum
admin.title=Konfiguration Forum
anonymous.course.default=Default for course forum
anonymous.default.enabled=Pseudonym enabled
anonymous.default.disabled=Pseudonym disabled
anonymous.course.default=Standardeinstellung f\u00FCr Kursforum
anonymous.default.enabled=Pseudonym aktiviert
anonymous.default.disabled=Pseudonym deaktiviert
anonymous.group.default=Default for group forum
anonymous.posting=Erlaubt anonymous posting using a pseudonym
anonymous.posting=Anonymes Schreiben mit einem Pseudonym gestatten
anonymous.poster=Gastbeitrag
guest=Gast
guest.suffix=(Gast)
......@@ -17,7 +17,7 @@ archive.thread=Diskussionsthema archivieren
archive.thread.dialog=Wollen Sie dieses Diskussionsthema wirklich in Ihrem pers\u00F6nlichen Ordner im Unterordner "private/archive" archivieren?
archive.thread.successfully=Das Diskussionsthema wurde in Ihrem pers\u00F6nlichen Ordner im Unterordner "private/archive" archiviert.
attachments=Dateianh\u00E4nge
attachments.too.big=Dateianhang ist zu gross. Es sind maximal {0} MB möglich.
attachments.too.big=Dateianhang ist zu gross. Es sind maximal {0} MB m\u00F6glich.
attachments.upload.successful=Die Datei {0} wurde erfolgreich hochgeladen. Bei Bedarf können noch weitere Dateien angehängt werden.
attachments.error.file.exists=Diese Datei existiert bereits und kann nicht erneut hochgeladen werden.
attachments.remove.string=löschen
......
......@@ -145,6 +145,7 @@ public class ThreadListController extends FormBasicController {
threadTable = uifactory.addTableElement(getWindowControl(), "threads", threadTableModel, getTranslator(), formLayout);
threadTable.setCustomizeColumns(false);
threadTable.setElementCssClass("o_forum");
threadTable.setEmtpyTableMessageKey("forum.emtpy");
}
@Override
......
<div class="o_sel_forum">
#if($r.available("subscription"))
$r.render("subscription")
#end
$r.render("forum")
\ No newline at end of file
$r.render("forum")
</div>
\ No newline at end of file
......@@ -97,6 +97,8 @@ public class RepositoryModule extends AbstractSpringModule {
NewControllerFactory.getInstance().addContextEntryControllerCreator(CatalogEntry.class.getSimpleName(),
new CatalogContextEntryControllerCreator(this));
NewControllerFactory.getInstance().addContextEntryControllerCreator("Catalog",
new CatalogContextEntryControllerCreator(this));
NewControllerFactory.getInstance().addContextEntryControllerCreator("CatalogAdmin",
new SiteContextEntryControllerCreator(CatalogAdminSite.class));
......
......@@ -81,6 +81,13 @@ public class CatalogSiteMainController extends BasicController implements Activa
return;
}
ContextEntry entry = entries.get(0);
String type = entry.getOLATResourceable().getResourceableTypeName();
if("Catalog".equalsIgnoreCase(type)) {
//remove the Catalog/0
entries = entries.subList(1, entries.size());
}
stackPanel.popUpToRootController(ureq);
nodeController.activate(ureq, entries, state);
}
......
......@@ -80,6 +80,35 @@ public class BusinessGroupTest {
@Page
private NavigationPage navBar;
/**
* Create a group, search it and delete it.
*
* @param loginPage
* @throws IOException
* @throws URISyntaxException
*/
@Test
@RunAsClient
public void createDeleteBusinessGroup(@InitialPage LoginPage loginPage)
throws IOException, URISyntaxException {
UserVO author = new UserRestClient(deploymentUrl).createAuthor();
loginPage
.loginAs(author.getLogin(), author.getPassword())
.resume();
//go to groups
String groupName = "Delete-1-" + UUID.randomUUID();
navBar
.openGroups(browser)
.createGroup(groupName, "A very little group to delete");
//return to group list and delete it
navBar
.openGroups(browser)
.deleteGroup(groupName)
.assertDeleted(groupName);
}
/**
* An author create a group, set the visibility to
......
......@@ -222,6 +222,111 @@ public class CourseTest {
}
}
/**
* An author create a course, add a second user as co-author
* of the course, and edit the course.<br>
* The co-author select the course and try to edit it, unsuccessfully.
* It try to edit the course directly from the author list without
* success.<br>
* The author closes the editor and the co-author is allowed to edit.
* The author cannot edit i anymore...
*
* @param loginPage Login page of the author
* @param coAuthorBrowser the browser for the coauthor
*/
@Test
@RunAsClient
public void concurrentEditCourse(@InitialPage LoginPage loginPage,
@Drone @Participant WebDriver coAuthorBrowser)
throws IOException, URISyntaxException {
UserVO author = new UserRestClient(deploymentUrl).createAuthor();
UserVO coAuthor = new UserRestClient(deploymentUrl).createAuthor();
loginPage
.loginAs(author.getLogin(), author.getPassword())
.resume();
//go to authoring
AuthoringEnvPage authoringEnv = navBar
.assertOnNavigationPage()
.openAuthoringEnvironment();
String title = "Concurrent-Edit-" + UUID.randomUUID().toString();
//create course
authoringEnv
.openCreateDropDown()
.clickCreate(ResourceType.course)
.fillCreateForm(title)
.assertOnGeneralTab()
.clickToolbarBack();
//add a second owner
MembersPage members = new CoursePageFragment(browser)
.members();
members
.addMember()
.searchMember(coAuthor, true)
.next()
.next()
.selectRepositoryEntryRole(true, false, false)
.next()
.finish();
//open the editor
CoursePageFragment coursePage = members
.clickToolbarBack();
CourseEditorPageFragment editor = coursePage
.edit();
//the second author come in
LoginPage coAuthroLoginPage = LoginPage.getLoginPage(coAuthorBrowser, deploymentUrl);
coAuthroLoginPage
.loginAs(coAuthor.getLogin(), coAuthor.getPassword())
.resume();
//go to authoring
NavigationPage coAuthorNavBar = new NavigationPage(coAuthorBrowser);
coAuthorNavBar
.assertOnNavigationPage()
.openAuthoringEnvironment()
.selectResource(title);
//try to edit
CoursePageFragment coAuthorCourse = new CoursePageFragment(coAuthorBrowser);
coAuthorCourse
.edit()
.assertOnWarning();
//retry in list
coAuthorNavBar
.openAuthoringEnvironment()
.editResource(title);
new CourseEditorPageFragment(coAuthorBrowser)
.assertOnWarning();
//author close the course editor
editor
.clickToolbarBack();
coursePage
.assertOnCoursePage();
//co-author edit the course
CourseEditorPageFragment coAuthorEditor = coAuthorCourse
.edit()
.assertOnEditor();
//author try
coursePage
.edit()
.assertOnWarning();
//co-author close the editor
coAuthorEditor
.clickToolbarBack()
.assertOnCoursePage();
//author reopens the editor
coursePage
.edit()
.assertOnEditor();
}
/**
* Create a course, create a CP, go the the course editor,
* create a course element of type CP, select the CP which just created,
......
......@@ -80,12 +80,9 @@ public class NavigationPage {
public AuthoringEnvPage openAuthoringEnvironment() {
navigate(authoringEnvTabBy);
backToTheTop();
OOGraphene.closeBlueMessageWindow(browser);
WebElement main = browser.findElement(By.id("o_main"));
return Graphene.createPageFragment(AuthoringEnvPage.class, main);
return new AuthoringEnvPage(browser);
}
public PortalPage openPortal() {
......
......@@ -38,6 +38,8 @@ import org.openqa.selenium.WebElement;
*/
public class FolderPage {
public static final By folderBy = By.cssSelector("div.o_briefcase_folder");
@Drone
private WebDriver browser;
......
......@@ -22,7 +22,6 @@ package org.olat.selenium.page.course;
import java.util.ArrayList;
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;
......@@ -31,7 +30,6 @@ import org.olat.selenium.page.repository.AuthoringEnvPage;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
/**
*
......@@ -72,20 +70,31 @@ public class CourseEditorPageFragment {
chooseRepoEntriesButtonList.add(choosePortfolioButton);
}
@Drone
private WebDriver browser;
@FindBy(className="o_course_editor")
private WebElement editor;
public CourseEditorPageFragment(WebDriver browser) {
this.browser = browser;
}
public static CourseEditorPageFragment getEditor(WebDriver browser) {
OOGraphene.waitElement(editorBy, browser);
WebElement main = browser.findElement(By.id("o_main"));
return Graphene.createPageFragment(CourseEditorPageFragment.class, main);
OOGraphene.closeBlueMessageWindow(browser);
return new CourseEditorPageFragment(browser);
}
public CourseEditorPageFragment assertOnEditor() {
Assert.assertTrue(editor.isDisplayed());
List<WebElement> editorEls = browser.findElements(editorBy);
Assert.assertFalse(editorEls.isEmpty());
Assert.assertTrue(editorEls.get(0).isDisplayed());
return this;
}
public CourseEditorPageFragment assertOnWarning() {
By warningBy = By.cssSelector("div.modal-dialog div.alert.alert-warning");
OOGraphene.waitElement(warningBy, 2, browser);
List<WebElement> warningEls = browser.findElements(warningBy);
Assert.assertFalse(warningEls.isEmpty());
OOGraphene.closeModalDialogWindow(browser);
return this;
}
......
......@@ -170,9 +170,7 @@ public class CoursePageFragment {
browser.findElement(editCourseBy).click();
OOGraphene.waitBusy(browser);
OOGraphene.closeBlueMessageWindow(browser);
WebElement main = browser.findElement(By.id("o_main"));
return Graphene.createPageFragment(CourseEditorPageFragment.class, main);
return new CourseEditorPageFragment(browser);
}
/**
......
......@@ -111,8 +111,6 @@ public class MembersPage {
WebElement submitButton = browser.findElement(submitBy);
submitButton.click();
OOGraphene.waitBusy(browser);
return this;
}
......
......@@ -40,6 +40,8 @@ public class ForumPage {
private WebDriver browser;
public static final By threadTableBy = By.cssSelector("div.o_sel_forum");
public ForumPage(WebDriver browser) {
this.browser = browser;
}
......@@ -51,7 +53,7 @@ public class ForumPage {
* @return
*/
public static ForumPage getCourseForumPage(WebDriver browser) {
By forumBy = By.cssSelector("div.o_course_run div.o_forum");
By forumBy = By.cssSelector("div.o_course_run div.o_sel_forum");
List<WebElement> forumEl = browser.findElements(forumBy);
Assert.assertFalse(forumEl.isEmpty());
......@@ -62,7 +64,7 @@ public class ForumPage {
}
public static ForumPage getGroupForumPage(WebDriver browser) {
By forumBy = By.cssSelector("div.o_forum");
By forumBy = By.cssSelector("div.o_sel_forum");
List<WebElement> forumEl = browser.findElements(forumBy);
Assert.assertFalse(forumEl.isEmpty());
return new ForumPage(browser);
......
......@@ -47,6 +47,7 @@ public class OOGraphene {
private static final long poolingDuration = 25;
private static final By closeBlueBoxButtonBy = By.cssSelector("div.o_alert_info div.o_sel_info_message i.o_icon.o_icon_close");
private static final By closeModalDialogButtonBy = By.cssSelector("div.modal-dialog div.modal-header button.close");
public static void waitBusy(WebDriver browser) {
Graphene.waitModel(browser).pollingEvery(poolingDuration, TimeUnit.MILLISECONDS).until(new BusyPredicate());
......@@ -70,6 +71,8 @@ public class OOGraphene {
Graphene.waitModel(browser).pollingEvery(poolingDuration, TimeUnit.MILLISECONDS).until().element(element).is().visible();
}
// 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) {
Graphene.waitModel(browser).withTimeout(5, TimeUnit.SECONDS)
.pollingEvery(poolingDuration, TimeUnit.MILLISECONDS).until(new TinyMCELoadedPredicate());
......@@ -212,6 +215,33 @@ public class OOGraphene {
}
}
public static final void closeModalDialogWindow(WebDriver browser) {
List<WebElement> closeButtons = browser.findElements(closeModalDialogButtonBy);
for(WebElement closeButton:closeButtons) {
if(closeButton.isDisplayed()) {
try {
clickModalDialogCloseButton(browser, closeButton);
} catch (TimeoutException e) {
try {
clickModalDialogCloseButton(browser, closeButton);
} catch(Exception e2) {
//
}
}
}
}
}
private static final void clickModalDialogCloseButton(WebDriver browser, WebElement closeButton) {
try {
closeButton.click();
By dialogBy = By.cssSelector("div.modal-dialog");
OOGraphene.waitElementDisappears(dialogBy, 2, browser);
} catch (ElementNotVisibleException e) {
//e.printStackTrace();
}
}
/*public static void closeOffCanvas(WebDriver browser) {
By closeBy = By.cssSelector("a.o_offcanvas_close");
List<WebElement> closeButtons = browser.findElements(closeBy);
......
......@@ -123,6 +123,7 @@ public class GroupPage {
public IMPage openChat() {
openMenuItem(chatTool);
OOGraphene.waitElement(By.cssSelector("a.o_sel_im_open_tool_chat"), 2, browser);
return new IMPage(browser);
}
......@@ -134,34 +135,42 @@ public class GroupPage {
public ContactPage openContact() {
openMenuItem(contactTool);
OOGraphene.waitElement(By.cssSelector("fieldset.o_sel_contact_form"), 2, browser);
return new ContactPage(browser);
}
public GroupPage openMembers() {
return openMenuItem(membersTool);
openMenuItem(membersTool);
return this;
}
public GroupPage openNews() {
return openMenuItem(newsTool);
openMenuItem(newsTool);
OOGraphene.waitElement(By.id("o_msg_info"), 2, browser);
return this;
}
public FolderPage openFolder() {
openMenuItem(folderTool);
OOGraphene.waitElement(FolderPage.folderBy, 2, browser);
return new FolderPage(browser);
}
public ForumPage openForum() {
openMenuItem(forumTool);
OOGraphene.waitElement(ForumPage.threadTableBy, 2, browser);
return ForumPage.getGroupForumPage(browser);
}
public WikiPage openWiki() {
openMenuItem(wikiTool);
OOGraphene.waitElement(WikiPage.wikiWrapperBy, 2, browser);
return WikiPage.getGroupWiki(browser);
}
public PortfolioPage openPortfolio() {
openMenuItem(portfolioTool);
OOGraphene.waitElement(PortfolioPage.mapBy, 2, browser);
return new PortfolioPage(browser);
}
......
......@@ -140,4 +140,27 @@ public class GroupsPage {
OOGraphene.waitBusy(browser);
return this;
}
public GroupsPage deleteGroup(String name) {
By groupNameBy = By.xpath("//table//td[//a[text()[contains(.,'" + name+ "')]]]//a[contains(@href,'bgTblDelete')]");
browser.findElement(groupNameBy).click();
OOGraphene.waitBusy(browser);
//wait confirm dialog
By popupBy = By.cssSelector("div.modal-dialog");
OOGraphene.waitElement(popupBy, 2, browser);
By okBy = By.cssSelector("div.modal-dialog button.btn.btn-primary");
browser.findElement(okBy).click();
OOGraphene.waitBusy(browser);
OOGraphene.waitAndCloseBlueMessageWindow(browser);
return this;
}
public GroupsPage assertDeleted(String name) {
By groupNameBy = By.xpath("//table//td[//a[text()[contains(.,'" + name+ "')]]]");
List<WebElement> groupEls = browser.findElements(groupNameBy);
Assert.assertTrue(groupEls.isEmpty());
return this;
}
}
......@@ -108,6 +108,30 @@ public class MembersWizardPage {
return this;
}
public MembersWizardPage selectRepositoryEntryRole(boolean owner, boolean coach, boolean participant) {
if(owner) {
By ownerBy = By.cssSelector("label input[name='repoRights'][type='checkbox'][value='owner']");
WebElement ownerEl = browser.findElement(ownerBy);
OOGraphene.check(ownerEl, new Boolean(owner));
OOGraphene.waitBusy(browser);
}
if(coach) {
By coachBy = By.cssSelector("label input[name='repoRights'][type='checkbox'][value='tutor']");
WebElement coachEl = browser.findElement(coachBy);
OOGraphene.check(coachEl, new Boolean(coach));
OOGraphene.waitBusy(browser);
}
if(participant) {
By participantBy = By.cssSelector("label input[name='repoRights'][type='checkbox'][value='participant']");
WebElement participantEl = browser.findElement(participantBy);
OOGraphene.check(participantEl, new Boolean(participant));
OOGraphene.waitBusy(browser);
}
return this;
}
public MembersWizardPage selectGroupAsParticipant(String groupName) {
By rolesBy = By.xpath("//div[contains(@class,'o_table_wrapper')]//table//tr[td[text()='" + groupName + "']]//label[contains(@class,'o_sel_role_participant')]/input");
List<WebElement> roleEls = browser.findElements(rolesBy);
......
......@@ -38,6 +38,8 @@ import org.openqa.selenium.WebElement;
*/
public class PortfolioPage {
public static final By mapBy = By.cssSelector("div.o_eportfolio_map");
@Drone
private WebDriver browser;
......@@ -244,11 +246,11 @@ public class PortfolioPage {
}
public PortfolioPage openMap(String mapTitle) {
By mapBy = By.cssSelector("div.o_eportfolio_maps div.o_map-default");
By defaultMapBy = By.cssSelector("div.o_eportfolio_maps div.o_map-default");
By headingBy = By.cssSelector("div.panel-heading h4");
By openBy = By.className("o_sel_ep_open_map");
List<WebElement> mapEls = browser.findElements(mapBy);
List<WebElement> mapEls = browser.findElements(defaultMapBy);
WebElement mapEl = null;
for(WebElement el:mapEls) {
WebElement headingEl = el.findElement(headingBy);
......
......@@ -21,7 +21,6 @@ package org.olat.selenium.page.repository;
import java.io.File;
import org.jboss.arquillian.drone.api.annotation.Drone;
import org.jboss.arquillian.graphene.Graphene;
import org.junit.Assert;
import org.olat.selenium.page.course.CourseWizardPage;
......@@ -47,9 +46,12 @@ public class AuthoringEnvPage {
public static final By createMenuCaretBy = By.cssSelector("a.o_sel_author_create");
public static final By createMenuBy = By.cssSelector("ul.o_sel_author_create");
@Drone
private WebDriver browser;
public AuthoringEnvPage(WebDriver browser) {
this.browser = browser;
}
public RepositoryEditDescriptionPage createCP(String title) {
return openCreateDropDown()
.clickCreate(ResourceType.cp)
......@@ -166,10 +168,21 @@ public class AuthoringEnvPage {
WebElement saveButton = browser.findElement(saveBy);
saveButton.click();
OOGraphene.waitBusy(browser);
return this;
}
public void selectResource(String title) {
By selectBy = By.xpath("//div[contains(@class,'o_coursetable')]//a[contains(text(),'" + title + "')]");
browser.findElement(selectBy).click();
OOGraphene.waitBusy(browser);
}
public void editResource(String title) {
By editBy = By.xpath("//div[contains(@class,'o_coursetable')]//tr[//a[contains(text(),'" + title + "')]]//a[contains(@href,'edit')]");
browser.findElement(editBy).click();
OOGraphene.waitBusy(browser);
}
public enum ResourceType {
course("CourseModule"),
cp("FileResource.IMSCP"),
......
......@@ -50,6 +50,7 @@ public class CPPage {
List<WebElement> iframes = browser.findElements(iframeBy);
browser = browser.switchTo().frame(iframes.get(0));
OOGraphene.waitElement(by, 5, browser);
List<WebElement> elements = browser.findElements(by);
Assert.assertFalse(elements.isEmpty());
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment