Skip to content

Commit

Permalink
XWIKI-21848: Migrate NotificationFilterPreferenceLivetableResults to …
Browse files Browse the repository at this point in the history
…a Live Data source

  * Fix since values
  * Introduce integration tests
  * Introduce page objects for LiveData panels
  * Fix UserProfile PO to allow following user
  • Loading branch information
surli committed Mar 20, 2024
1 parent 16cb25b commit ee34d32
Show file tree
Hide file tree
Showing 25 changed files with 560 additions and 51 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.xwiki.livedata.test.po;

import org.openqa.selenium.By;
import org.openqa.selenium.InvalidElementStateException;
import org.openqa.selenium.Point;
import org.openqa.selenium.WebElement;
import org.xwiki.test.ui.po.BaseElement;

/**
* Abstract class representing different type of advanced panels in livedata.
*
* @version $Id$
* @since 16.3.0RC1
*/
public abstract class AbstractLiveDataAdvancedPanelElement extends BaseElement
{
protected final WebElement container;
protected final LiveDataElement liveData;

/**
* Default constructor.
* @param liveData the livedata the panel belongs to.
* @param container the container of the panel.
*/
public AbstractLiveDataAdvancedPanelElement(LiveDataElement liveData, WebElement container)
{
this.liveData = liveData;
this.container = container;
}

/**
* Close the panel.
*/
public void closePanel()
{
getDriver().findElementWithoutWaiting(this.container, By.className("close-button")).click();
}

/**
* Allow to click on links that are only visible when the mouse is on them (e.g. delete icons of filters)
* @param linkIdentifiers the identifier to find the link element in the dom.
*/
protected void clickOnMouseOverLinks(By linkContainer, By linkIdentifiers)
{
getDriver().findElementsWithoutWaiting(this.container, linkContainer)
.forEach(webElement -> {
// First we move to the link container to make the link appearing
getDriver().createActions().moveToElement(webElement).build().perform();
WebElement linkElement = getDriver().findElementWithoutWaiting(webElement, linkIdentifiers);
if (!linkElement.isDisplayed()) {
throw new InvalidElementStateException(String.format("The link [%s] should be displayed.",
linkElement));
}
// Click on the actual link
getDriver().createActions().moveToElement(linkElement).click().build().perform();
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.xwiki.livedata.test.po;

import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

/**
* Represents the advanced panel for filtering columns.
*
* @version $Id$
* @since 16.3.0RC1
*/
public class FiltersPanelElement extends AbstractLiveDataAdvancedPanelElement
{
/**
* Default constructor.
* @param liveData the livedata of the panel.
* @param container the container of the panel.
*/
public FiltersPanelElement(LiveDataElement liveData, WebElement container)
{
super(liveData, container);
}

/**
* Remove all filters.
*/
public void clearAllFilters()
{
this.clickOnMouseOverLinks(By.className("filter-group-title"), By.className("delete-filter-group"));
this.liveData.waitUntilReady();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,16 +104,21 @@ public boolean isReady()
return isVueLoaded() && areComponentsLoaded();
}

private WebElement openDropDownMenu()
{
WebElement dropdownMenu = getRootElement().findElement(By.cssSelector(".livedata-dropdown-menu "));
dropdownMenu.click();
return dropdownMenu;
}

/**
* Click on the refresh button from the actions menu.
*
* @since 15.5
*/
public void refresh()
{
WebElement dropdownMenu = getRootElement().findElement(By.cssSelector(".livedata-dropdown-menu "));
dropdownMenu.click();
dropdownMenu.findElement(By.cssSelector(".livedata-action-refresh")).click();
openDropDownMenu().findElement(By.cssSelector(".livedata-action-refresh")).click();
}

/**
Expand All @@ -139,7 +144,7 @@ public LiveDataElement setPagination(int paginationNumber)
return this;
}

private void waitUntilReady()
public void waitUntilReady()
{
getDriver().waitUntilCondition(input -> isVueLoaded());

Expand Down Expand Up @@ -180,4 +185,48 @@ private WebElement getRootElement()
{
return getDriver().findElement(By.id(this.id));
}

/**
* Open the panel for advanced filter and returns it.
* @return an instance of {@link FiltersPanelElement} once it's opened.
* @since 16.3.0RC1
*/
public FiltersPanelElement openFiltersPanel()
{
openDropDownMenu().findElement(By.linkText("Filter...")).click();
return new FiltersPanelElement(this,
getRootElement().findElement(By.className("livedata-advanced-panel-filter")));
}

/**
* Open the panel for advanced sorting and returns it.
* @return an instance of {@link SortPanelElement} once it's opened.
* @since 16.3.0RC1
*/
public SortPanelElement openSortPanel()
{
openDropDownMenu().findElement(By.linkText("Sort...")).click();
return new SortPanelElement(this,
getRootElement().findElement(By.className("livedata-advanced-panel-sort")));
}

/**
* Clear all custom sorting that might have been put.
*/
public void clearAllSort()
{
SortPanelElement sortPanelElement = openSortPanel();
sortPanelElement.clearAllSort();
sortPanelElement.closePanel();
}

/**
* Clear all custom filters that might have been put.
*/
public void clearAllFilters()
{
FiltersPanelElement filtersPanelElement = openFiltersPanel();
filtersPanelElement.clearAllFilters();
filtersPanelElement.closePanel();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.xwiki.livedata.test.po;

import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

/**
* Represents the advanced panel for sorting columns.
*
* @version $Id$
* @since 16.3.0RC1
*/
public class SortPanelElement extends AbstractLiveDataAdvancedPanelElement
{
/**
* Default constructor.
* @param liveData the livedata of the panel.
* @param container the container of the panel.
*/
public SortPanelElement(LiveDataElement liveData, WebElement container)
{
super(liveData, container);
}

/**
* Remove all sorting on all columns.
*/
public void clearAllSort()
{
this.clickOnMouseOverLinks(By.className("sort-entry"), By.className("delete-sort"));
this.liveData.waitUntilReady();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import org.apache.http.NameValuePair;
Expand Down Expand Up @@ -76,6 +77,9 @@ public class TableLayoutElement extends BaseElement

private final LiveDataElement liveData;

private static final Pattern PAGINATION_SENTENCE_PATTERN =
Pattern.compile("^Entries (?<firstEntry>\\d+) - (?<lastEntry>\\d+) out of (?<totalEntries>\\d+)$");

/**
* @return the list of rows {@link WebElement}s
* @since 16.1.0RC1
Expand Down Expand Up @@ -688,6 +692,24 @@ public Set<String> getPaginationSizes()
.map(it -> it.getAttribute("value")).collect(Collectors.toSet());
}

private String getPaginationEntriesString()
{
return getRoot().findElement(By.className("pagination-current-entries")).getText().trim();
}

private java.util.regex.Matcher getPaginationMatcher()
{
return PAGINATION_SENTENCE_PATTERN.matcher(getPaginationEntriesString());
}

public long getTotalEntries()
{
java.util.regex.Matcher paginationMatcher = getPaginationMatcher();
if (!paginationMatcher.matches()) {
throw new IllegalStateException("Matcher does not match: " + getPaginationEntriesString());
}
return Long.parseLong(paginationMatcher.group("totalEntries"));
}

/**
* Clicks on an action button identified by its name, on a given row.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
* Provide information about the activation of {@link ToggleableNotificationFilter}.
*
* @version $Id$
* @since 16.2.0RC1
* @since 16.3.0RC1
*/
public class ToggleableNotificationFilterActivation implements Serializable
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public class NotificationFilterPreferenceStore
* @param filterPreferenceId a filter preference id
* @return the corresponding preference or {@link Optional#empty()} if none can be found
* @throws NotificationException if an error occurs
* @since 16.2.0RC1
* @since 16.3.0RC1
*/
public Optional<NotificationFilterPreference> getFilterPreference(String filterPreferenceId,
WikiReference wikiReference) throws NotificationException
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,20 @@ public class ToggleableFilterPreferenceDocumentInitializer extends AbstractManda
{
/**
* Reference of the xclass.
* @since 16.3.0RC1
*/
public static final LocalDocumentReference XCLASS =
new LocalDocumentReference(List.of("XWiki", "Notifications", "Code"), "ToggleableFilterPreferenceClass");

/**
* Name of field holding the filter name.
* @since 16.3.0RC1
*/
public static final String FIELD_FILTER_NAME = "filterName";

/**
* Name of the field holding the activation value.
* @since 16.3.0RC1
*/
public static final String FIELD_IS_ENABLED = "isEnabled";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
* {@link org.xwiki.notifications.filters.internal.livedata.system.NotificationSystemFiltersLiveDataEntryStore}.
*
* @version $Id$
* @since 16.2.0RC1
* @since 16.3.0RC1
*/
public abstract class AbstractNotificationFilterLiveDataEntryStore implements LiveDataEntryStore
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
* Helper for getting various translations for live data custom sources.
*
* @version $Id$
* @since 16.2.0RC1
* @since 16.3.0RC1
*/
@Component(roles = NotificationFilterLiveDataTranslationHelper.class)
@Singleton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
/**
* Configuration of the {@link NotificationCustomFiltersLiveDataSource}.
*
* @since 16.3.0RC1
* @version $Id$
*/
@Component
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
/**
* Needed component for the live data configuration.
*
* @since 16.3.0RC1
* @version $Id$
*/
@Component
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
* Dedicated {@link LiveDataEntryStore} for the {@link NotificationCustomFiltersLiveDataSource}.
* This component is in charge of performing the actual HQL queries to display the live data.
*
* @since 16.3.0RC1
* @version $Id$
*/
@Component
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
/**
* Descriptor for the {@link NotificationCustomFiltersLiveDataSource}.
*
* @since 16.3.0RC1
* @version $Id$
*/
@Component
Expand Down
Loading

0 comments on commit ee34d32

Please sign in to comment.