diff --git a/application-analytics-default/pom.xml b/application-analytics-default/pom.xml index f048b51..02ca7f7 100644 --- a/application-analytics-default/pom.xml +++ b/application-analytics-default/pom.xml @@ -66,6 +66,10 @@ jersey-client 2.30.1 + + org.apache.commons + commons-lang3 + diff --git a/application-analytics-default/src/main/java/com/xwiki/analytics/internal/MostViewedJsonNormaliser.java b/application-analytics-default/src/main/java/com/xwiki/analytics/internal/MostViewedJsonNormaliser.java index bb25faa..aba46c3 100644 --- a/application-analytics-default/src/main/java/com/xwiki/analytics/internal/MostViewedJsonNormaliser.java +++ b/application-analytics-default/src/main/java/com/xwiki/analytics/internal/MostViewedJsonNormaliser.java @@ -30,6 +30,7 @@ import javax.inject.Named; import javax.inject.Singleton; +import org.apache.commons.lang3.exception.ExceptionUtils; import org.xwiki.component.annotation.Component; import org.xwiki.resource.CreateResourceReferenceException; import org.xwiki.resource.CreateResourceTypeException; @@ -45,7 +46,6 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import com.xwiki.analytics.JsonNormaliser; -import org.apache.commons.lang3.exception.ExceptionUtils; /** * Implementation for {@link JsonNormaliser}. diff --git a/application-analytics-test/application-analytics-test-docker/pom.xml b/application-analytics-test/application-analytics-test-docker/pom.xml new file mode 100644 index 0000000..60bdbfd --- /dev/null +++ b/application-analytics-test/application-analytics-test-docker/pom.xml @@ -0,0 +1,148 @@ + + + + + + 4.0.0 + + com.xwiki.analytics + application-analytics-test + 1.0-SNAPSHOT + + application-analytics-test-docker + jar + Functional tests for the Analytics Application (Pro) + + + true + + + + + + com.xwiki.licensing + application-licensing-test-api + ${licensing.version} + runtime + + + + org.xwiki.platform + xwiki-platform-menu-ui + ${platform.version} + xar + + + com.xwiki.analytics + application-analytics-ui + ${project.version} + xar + + + + com.xwiki.licensing + application-licensing-licensor-api + + + + + + + + com.xwiki.analytics + application-analytics-test-pageobjects + ${project.version} + test + + + org.xwiki.platform + xwiki-platform-model-api + ${platform.version} + + + org.xwiki.commons + xwiki-commons-extension-api + ${commons.version} + + + com.google.code.findbugs + jsr305 + 3.0.2 + + + + org.xwiki.platform + xwiki-platform-test-docker + ${platform.version} + test + + + com.xwiki.licensing + application-licensing-test-dependencies + ${licensing.version} + pom + test + + + + src/test/it + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + + + + clover + + + + org.openclover + clover + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + + + xwiki.test.ui.profiles + clover + + + + + + + + + \ No newline at end of file diff --git a/application-analytics-test/application-analytics-test-docker/src/test/it/com/xwiki/analytics/test/ui/AllITs.java b/application-analytics-test/application-analytics-test-docker/src/test/it/com/xwiki/analytics/test/ui/AllITs.java new file mode 100644 index 0000000..62c25ea --- /dev/null +++ b/application-analytics-test/application-analytics-test-docker/src/test/it/com/xwiki/analytics/test/ui/AllITs.java @@ -0,0 +1,34 @@ +/* + * 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 com.xwiki.analytics.test.ui; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.xwiki.test.docker.junit5.UITest; + +@UITest +public class AllITs +{ + @Nested + @DisplayName("Analytics UI Test") + class NestedAnalyticsIT extends AnalyticsIT + { + } +} diff --git a/application-analytics-test/application-analytics-test-docker/src/test/it/com/xwiki/analytics/test/ui/AnalyticsIT.java b/application-analytics-test/application-analytics-test-docker/src/test/it/com/xwiki/analytics/test/ui/AnalyticsIT.java new file mode 100644 index 0000000..ed44dc7 --- /dev/null +++ b/application-analytics-test/application-analytics-test-docker/src/test/it/com/xwiki/analytics/test/ui/AnalyticsIT.java @@ -0,0 +1,220 @@ +/* + * 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 com.xwiki.analytics.test.ui; + +import java.util.Collections; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.openqa.selenium.By; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.MySQLContainer; +import org.testcontainers.utility.DockerImageName; +import org.xwiki.test.docker.internal.junit5.DockerTestUtils; +import org.xwiki.test.docker.junit5.TestConfiguration; +import org.xwiki.test.docker.junit5.UITest; +import org.xwiki.test.ui.TestUtils; +import org.xwiki.test.ui.XWikiWebDriver; + +import com.xwiki.analytics.test.po.AnalyticsAdministrationSectionPage; +import com.xwiki.analytics.test.po.AnalyticsViewPage; +import com.xwiki.analytics.test.po.MatomoTestUtils; +import com.xwiki.analytics.test.po.MostViewedPagesElement; +import com.xwiki.analytics.test.po.RowEvolutionModal; +import com.xwiki.analytics.test.ui.config.Config; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@UITest +class AnalyticsIT +{ + @BeforeAll + void setup(XWikiWebDriver driver, TestConfiguration testConfiguration, TestUtils testUtils) throws Exception + { + setupContainers(driver, testConfiguration); + setupUIExtension(testUtils); + setupUsers(testUtils); + } + + /** + * Check that the Save button displays the correct messages when the configurations provided by the users are + * incorrect. + */ + @Test + @Order(1) + void checkWrongConfigs(XWikiWebDriver driver) throws InterruptedException + { + AnalyticsViewPage.gotoPage(); + AnalyticsAdministrationSectionPage analyticsConfigViewPage = new AnalyticsAdministrationSectionPage(); + analyticsConfigViewPage.gotoPage(); + analyticsConfigViewPage.setTrackingCode("").setAuthTokenId(Config.MATOMO_AUTH_TOKEN).setIdSiteId("1") + .setRequestAddressId(Config.ADDRESS + ":" + Config.MATOMO_BRIDGE_PORT).saveConfigs(); + + analyticsConfigViewPage.waitForNotificationInProgressMessage("Saving..."); + analyticsConfigViewPage.waitForNotificationSuccessMessage("Saved"); + analyticsConfigViewPage.waitForNotificationInProgressMessage("Checking connection to Matomo."); + analyticsConfigViewPage.waitForNotificationErrorMessage( + "Failed to connect to Matomo. Please check your configuration values."); + } + + /** + * Check that the Save button displays the correct messages when the configurations provided by the users are + * correct. + */ + @Test + @Order(2) + void checkValidConfigs(XWikiWebDriver driver) throws InterruptedException + { + AnalyticsViewPage.gotoPage(); + AnalyticsAdministrationSectionPage analyticsConfigViewPage = new AnalyticsAdministrationSectionPage(); + analyticsConfigViewPage.gotoPage(); + analyticsConfigViewPage.setTrackingCode(Config.getTrackingCode()).setAuthTokenId(Config.MATOMO_AUTH_TOKEN) + .setIdSiteId("1").setRequestAddressId("http://" + Config.ADDRESS + ":" + Config.MATOMO_BRIDGE_PORT + "/") + .saveConfigs(); + analyticsConfigViewPage.waitForNotificationInProgressMessage("Saving..."); + analyticsConfigViewPage.waitForNotificationSuccessMessage("Saved"); + analyticsConfigViewPage.waitForNotificationInProgressMessage("Checking connection to Matomo."); + analyticsConfigViewPage.waitForNotificationSuccessMessage("Test connection succeeded!"); + } + + /** + * Checks if the admin has edit permissions in the home page of the application. + */ + @Test + @Order(3) + void checkEditPermissionsForAdmin(XWikiWebDriver driver) throws InterruptedException + { + + AnalyticsViewPage analyticsViewPage = AnalyticsViewPage.gotoPage(); + assertTrue(analyticsViewPage.hasEditButton()); + } + + /** + * Checks if a user has view permissions in the home page of the application. + */ + @Test + @Order(4) + void checkEditPermisionForUser(XWikiWebDriver driver, TestUtils testUtils) throws InterruptedException + { + testUtils.createUser("test", "test", null); + // Logout from the admin account + testUtils.setSession(null); + testUtils.login("test", "test"); + AnalyticsViewPage analyticsViewPage = AnalyticsViewPage.gotoPage(); + assertEquals("You are not allowed to view this page or perform this action.", + driver.findElement(By.cssSelector("p.xwikimessage")).getText()); + // Login as the admin to run the next test + testUtils.setSession(null); + testUtils.loginAsAdmin(); + } + + /** + * Checks that the Row Evolution modal is loaded properly. + */ + @Test + @Order(5) + void checkRowEvolutionModal() + { + AnalyticsViewPage.gotoPage(); + MostViewedPagesElement mostViewedPagesElement = new MostViewedPagesElement(); + RowEvolutionModal rowEvolutionModal = mostViewedPagesElement.openModal(); + assertTrue(rowEvolutionModal.isDisplayed()); + } + + /** + * Creates the Admin user + */ + private void setupUsers(TestUtils testUtils) + { + testUtils.loginAsSuperAdmin(); + // TODO: remove this line after upgrading the XWiki parent to a version >= 15.10, because it was added as part + // of the createAdminUser method + testUtils.setGlobalRights("XWiki.XWikiAdminGroup", "", "admin", true); + testUtils.createAdminUser(); + testUtils.loginAsAdmin(); + } + + /** + * Start the matomo and sql containers, rename the matomo.js to a random int to force the browser to load the + * tracking script without explicit settings and generate a new auth token for matomo to be used in the tests. + */ + private void setupContainers(XWikiWebDriver driver, TestConfiguration testConfiguration) throws Exception + { + GenericContainer sqlContainer = startDb(testConfiguration); + GenericContainer matomoContainer = startMatomo(testConfiguration, sqlContainer); + // Modify the name of the matomo.js to make sure that the browser doesn't block it. + matomoContainer.execInContainer("sh", "-c", + "grep -rl 'matomo.js' /var/www/html/ | xargs -d '\\n' -I {} sed -i 's/matomo.js/36011373.js/g' \"{}\""); + matomoContainer.execInContainer("sh", "-c", "mv /var/www/html/matomo.js /var/www/html/36011373.js"); + Config.MATOMO_AUTH_TOKEN = + MatomoTestUtils.createToken("http://" + Config.ADDRESS + ":" + matomoContainer.getMappedPort(80), driver); + } + + /** + * Import the platform.html.head UIExtension point to make the tracking code work in the test environment. + * 'org.xwiki.platform:xwiki-platform-distribution-ui-base' but we didn't add it as a test dependency because it + * brings too many transitive dependencies that we don't need. + */ + private void setupUIExtension(TestUtils testUtils) throws Exception + { + testUtils.setWikiPreference("meta", + "#foreach($uix in $services.uix.getExtensions(\"org.xwiki.platform.html.head\"," + + " {'sortByParameter' : 'order'}))\n" + " $services.rendering.render($uix.execute(), 'xhtml/1.0')\n" + + "#end"); + } + + /** + * Create and start a container with the database. + */ + private MySQLContainer startDb(TestConfiguration testConfiguration) throws Exception + { + // Since the MySQL container is derived from the official MySQL image I have to mark the image as compatible + // with MySQLContainers. + DockerImageName sqlContainer = + DockerImageName.parse(Config.DB_CONTAINER_NAME).asCompatibleSubstituteFor("mysql"); + MySQLContainer mysqlContainer = + new MySQLContainer<>(sqlContainer).withDatabaseName(Config.DB_NAME).withUsername(Config.DB_USERNAME) + .withPassword(Config.DB_PASSWORD).withExposedPorts(3306); + mysqlContainer.setPortBindings( + Collections.singletonList(String.format("%d:%d", Config.DB_BRIDGE_PORT, Config.DB_CONTAINER_EXPOSED_PORT))); + DockerTestUtils.startContainer(mysqlContainer, testConfiguration); + return mysqlContainer; + } + + /** + * Creates&starts the Matomo container. + * + * @param testConfiguration test configuration + * @param dbContainer reference to the db container + */ + private GenericContainer startMatomo(TestConfiguration testConfiguration, GenericContainer dbContainer) + throws Exception + { + GenericContainer matomoContainer = new GenericContainer<>(Config.MATOMO_CONTAINER_NAME).withExposedPorts(80) + .withEnv("MATOMO_DATABASE_HOST", + Config.ADDRESS + ":" + dbContainer.getMappedPort(Config.DB_CONTAINER_EXPOSED_PORT)) + .withFileSystemBind("src/test/it/resources/config.ini.php", Config.MATOMO_CONFIG_FILE_PATH); + matomoContainer.setPortBindings(Collections.singletonList(String.format("%d:80", Config.MATOMO_BRIDGE_PORT))); + DockerTestUtils.startContainer(matomoContainer, testConfiguration); + return matomoContainer; + } +} diff --git a/application-analytics-test/application-analytics-test-docker/src/test/it/com/xwiki/analytics/test/ui/config/Config.java b/application-analytics-test/application-analytics-test-docker/src/test/it/com/xwiki/analytics/test/ui/config/Config.java new file mode 100644 index 0000000..c269845 --- /dev/null +++ b/application-analytics-test/application-analytics-test-docker/src/test/it/com/xwiki/analytics/test/ui/config/Config.java @@ -0,0 +1,69 @@ +/* + * 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 com.xwiki.analytics.test.ui.config; + +public class Config +{ + // The custom sql container is needed to skip the Matomo installation wizard. + public static final String DB_CONTAINER_NAME = "farcasut/custom-mysql:latest"; + + public static final int DB_CONTAINER_EXPOSED_PORT = 3306; + + public static final int DB_BRIDGE_PORT = 9034; + + public static final String DB_NAME = "matomo"; + + public static final String DB_USERNAME = "matomo"; + + public static final String DB_PASSWORD = "secret"; + + public static final String ADDRESS = "172.17.0.1"; + + public static final String MATOMO_CONTAINER_NAME = "matomo:4.15.1"; + + public static final String MATOMO_CONFIG_FILE_PATH = "/var/www/html/config/config.ini.php"; + + public static final int MATOMO_BRIDGE_PORT = 9999; + + public static final String MATOMO_CREDENTIALS = "ADMIN1"; + + public static String MATOMO_AUTH_TOKEN = ""; + + public static String getTrackingCode() + { + String sb = "\n" + + "\n" + + "\n"; + return sb; + } +} diff --git a/application-analytics-test/application-analytics-test-docker/src/test/it/resources/config.ini.php b/application-analytics-test/application-analytics-test-docker/src/test/it/resources/config.ini.php new file mode 100644 index 0000000..bec3429 --- /dev/null +++ b/application-analytics-test/application-analytics-test-docker/src/test/it/resources/config.ini.php @@ -0,0 +1,84 @@ +; DO NOT REMOVE THIS LINE +; file automatically generated or modified by Matomo; you can manually override the default values in global.ini.php by redefining them in this file. +[database] +host = "172.17.0.1" +username = "matomo" +password = "secret" +dbname = "matomo" +tables_prefix = "matomo_" +port = 9034 +charset = "utf8mb4" + +[General] +enable_trusted_host_check = 0 +salt = "221e020a358ad259431e9ec76ba8a941" +trusted_hosts[] = "localhost" +trusted_hosts[] = "localhost:9999" +debug = 1 + +[PluginsInstalled] +PluginsInstalled[] = "Diagnostics" +PluginsInstalled[] = "Login" +PluginsInstalled[] = "CoreAdminHome" +PluginsInstalled[] = "UsersManager" +PluginsInstalled[] = "SitesManager" +PluginsInstalled[] = "Installation" +PluginsInstalled[] = "Monolog" +PluginsInstalled[] = "Intl" +PluginsInstalled[] = "CoreVue" +PluginsInstalled[] = "CorePluginsAdmin" +PluginsInstalled[] = "CoreHome" +PluginsInstalled[] = "WebsiteMeasurable" +PluginsInstalled[] = "IntranetMeasurable" +PluginsInstalled[] = "CoreVisualizations" +PluginsInstalled[] = "Proxy" +PluginsInstalled[] = "API" +PluginsInstalled[] = "Widgetize" +PluginsInstalled[] = "Transitions" +PluginsInstalled[] = "LanguagesManager" +PluginsInstalled[] = "Actions" +PluginsInstalled[] = "Dashboard" +PluginsInstalled[] = "MultiSites" +PluginsInstalled[] = "Referrers" +PluginsInstalled[] = "UserLanguage" +PluginsInstalled[] = "DevicesDetection" +PluginsInstalled[] = "Goals" +PluginsInstalled[] = "Ecommerce" +PluginsInstalled[] = "SEO" +PluginsInstalled[] = "Events" +PluginsInstalled[] = "UserCountry" +PluginsInstalled[] = "GeoIp2" +PluginsInstalled[] = "VisitsSummary" +PluginsInstalled[] = "VisitFrequency" +PluginsInstalled[] = "VisitTime" +PluginsInstalled[] = "VisitorInterest" +PluginsInstalled[] = "RssWidget" +PluginsInstalled[] = "Feedback" +PluginsInstalled[] = "TwoFactorAuth" +PluginsInstalled[] = "CoreUpdater" +PluginsInstalled[] = "CoreConsole" +PluginsInstalled[] = "ScheduledReports" +PluginsInstalled[] = "UserCountryMap" +PluginsInstalled[] = "Live" +PluginsInstalled[] = "PrivacyManager" +PluginsInstalled[] = "ImageGraph" +PluginsInstalled[] = "Annotations" +PluginsInstalled[] = "MobileMessaging" +PluginsInstalled[] = "Overlay" +PluginsInstalled[] = "SegmentEditor" +PluginsInstalled[] = "Insights" +PluginsInstalled[] = "Morpheus" +PluginsInstalled[] = "Contents" +PluginsInstalled[] = "BulkTracking" +PluginsInstalled[] = "Resolution" +PluginsInstalled[] = "DevicePlugins" +PluginsInstalled[] = "Heartbeat" +PluginsInstalled[] = "Marketplace" +PluginsInstalled[] = "ProfessionalServices" +PluginsInstalled[] = "UserId" +PluginsInstalled[] = "CustomJsTracker" +PluginsInstalled[] = "Tour" +PluginsInstalled[] = "PagePerformance" +PluginsInstalled[] = "CustomDimensions" +PluginsInstalled[] = "JsTrackerInstallCheck" + diff --git a/application-analytics-test/application-analytics-test-pageobjects/pom.xml b/application-analytics-test/application-analytics-test-pageobjects/pom.xml new file mode 100644 index 0000000..0cd40b1 --- /dev/null +++ b/application-analytics-test/application-analytics-test-pageobjects/pom.xml @@ -0,0 +1,52 @@ + + + + + + 4.0.0 + + com.xwiki.analytics + application-analytics-test + 1.0-SNAPSHOT + + application-analytics-test-pageobjects + Application Analytics (Pro) - Test - Page Objects + jar + Application Analytics (Pro) - Test - Page Objects + + + org.xwiki.platform + xwiki-platform-test-ui + ${platform.version} + + + org.xwiki.platform + xwiki-platform-administration-test-pageobjects + ${platform.version} + + + org.xwiki.platform + xwiki-platform-ckeditor-test-pageobjects + ${platform.version} + jar + + + \ No newline at end of file diff --git a/application-analytics-test/application-analytics-test-pageobjects/src/main/java/com/xwiki/analytics/test/po/AnalyticsAdministrationSectionPage.java b/application-analytics-test/application-analytics-test-pageobjects/src/main/java/com/xwiki/analytics/test/po/AnalyticsAdministrationSectionPage.java new file mode 100644 index 0000000..30e6752 --- /dev/null +++ b/application-analytics-test/application-analytics-test-pageobjects/src/main/java/com/xwiki/analytics/test/po/AnalyticsAdministrationSectionPage.java @@ -0,0 +1,93 @@ +/* + * 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 com.xwiki.analytics.test.po; + +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; +import org.openqa.selenium.support.FindBy; +import org.xwiki.administration.test.po.AdministrationPage; +import org.xwiki.test.ui.po.ViewPage; + +/** + * Responsible for interacting with the configuration tab of the application. + */ +public class AnalyticsAdministrationSectionPage extends ViewPage +{ + @FindBy(id = "Analytics.Code.ConfigurationClass_0_trackingCode") + private WebElement tracking_code; + + @FindBy(id = "Analytics.Code.ConfigurationClass_0_authToken") + private WebElement auth_token; + + @FindBy(id = "Analytics.Code.ConfigurationClass_0_siteId") + private WebElement site; + + @FindBy(id = "Analytics.Code.ConfigurationClass_0_requestAddress") + private WebElement request_address; + + public AnalyticsAdministrationSectionPage() + { + + } + + public AnalyticsAdministrationSectionPage gotoPage() + { + AdministrationPage administrationPage = AdministrationPage.gotoPage(); + administrationPage.clickSection("Other", "Analytics"); + return new AnalyticsAdministrationSectionPage(); + } + + public AnalyticsAdministrationSectionPage setTrackingCode(String value) + { + tracking_code.clear(); + tracking_code.sendKeys(value); + return this; + } + + public AnalyticsAdministrationSectionPage setAuthTokenId(String value) + { + auth_token.clear(); + auth_token.sendKeys(value); + return this; + } + + public AnalyticsAdministrationSectionPage setIdSiteId(String value) + { + site.clear(); + site.sendKeys(value); + return this; + } + + public AnalyticsAdministrationSectionPage setRequestAddressId(String value) + { + request_address.clear(); + request_address.sendKeys(value); + return this; + } + + public AnalyticsAdministrationSectionPage saveConfigs() + { + WebElement saveButton = getUtil().getDriver().findElement(By.cssSelector(".btn.btn-primary")); + Actions actions = getUtil().getDriver().createActions(); + actions.moveToElement(saveButton).click().perform(); + return this; + } +} diff --git a/application-analytics-test/application-analytics-test-pageobjects/src/main/java/com/xwiki/analytics/test/po/AnalyticsEditPage.java b/application-analytics-test/application-analytics-test-pageobjects/src/main/java/com/xwiki/analytics/test/po/AnalyticsEditPage.java new file mode 100644 index 0000000..160412b --- /dev/null +++ b/application-analytics-test/application-analytics-test-pageobjects/src/main/java/com/xwiki/analytics/test/po/AnalyticsEditPage.java @@ -0,0 +1,86 @@ +/* + * 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 com.xwiki.analytics.test.po; + +import java.util.HashMap; +import java.util.Map; + +import org.openqa.selenium.By; +import org.xwiki.ckeditor.test.po.MacroDialogSelectModal; +import org.xwiki.model.reference.DocumentReference; +import org.xwiki.test.ui.po.editor.EditPage; + +/** + * Responsible for interacting with the main page of the application when the page is in edit mode. + */ +public class AnalyticsEditPage extends EditPage +{ + public AnalyticsEditPage() + { + } + + /** + * Adds a new macro to the homepage of the application. + * + * @param macroName name of the macro + * @return + */ + public AnalyticsEditPage addNewMacro(String macroName) + { + + this.clickAddGadget().selectMacro(macroName); + return this; + } + + public static AnalyticsEditPage gotoPage() + { + DocumentReference documentReference = new DocumentReference("xwiki", "Analytics", "WebHome"); + Map params = new HashMap<>(); + params.put("force", "1"); + getUtil().gotoPage(documentReference, "edit", params); + return new AnalyticsEditPage(); + } + + public AnalyticsViewPage saveDashboard() + { + this.clickSaveAndView(); + return new AnalyticsViewPage(); + } + + private AnalyticsEditPage clickAddGadget() + { + getDriver().findElement(By.cssSelector(".addgadget")).click(); + return this; + } + + private void selectMacro(String macroName) + { + MacroDialogSelectModal macroDialogSelectModal = new MacroDialogSelectModal(); + // Will bring into view the macro that I want to use. + getDriver().findElement(By.cssSelector(".macro-textFilter")).sendKeys(macroName); + macroDialogSelectModal.filterByText(macroName, 1); + macroDialogSelectModal.getFirstMacro(); + macroDialogSelectModal.clickSelect(); + // Right now the MacroDialogSelectModal doesn't have a method to press submit. + String css = ".modal.macro-editor-modal.in .modal-footer .btn-primary"; + getDriver().waitUntilElementIsEnabled(getUtil().getDriver().findElement(By.cssSelector(css))); + getDriver().findElement(By.cssSelector(css)).click(); + } +} diff --git a/application-analytics-test/application-analytics-test-pageobjects/src/main/java/com/xwiki/analytics/test/po/AnalyticsViewPage.java b/application-analytics-test/application-analytics-test-pageobjects/src/main/java/com/xwiki/analytics/test/po/AnalyticsViewPage.java new file mode 100644 index 0000000..8cb4421 --- /dev/null +++ b/application-analytics-test/application-analytics-test-pageobjects/src/main/java/com/xwiki/analytics/test/po/AnalyticsViewPage.java @@ -0,0 +1,54 @@ +/* + * 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 com.xwiki.analytics.test.po; + +import org.openqa.selenium.By; +import org.xwiki.test.ui.po.ViewPage; + +/** + * Responsible for interacting with the main page of the application when the page is in view mode. + */ +public class AnalyticsViewPage extends ViewPage +{ + public AnalyticsViewPage() + { + } + + public static AnalyticsViewPage gotoPage() + { + getUtil().gotoPage("Analytics", "WebHome"); + return new AnalyticsViewPage(); + } + + /** + * Calculates the number of gadgets that are present on the homepage of the application. + * + * @return number of gadgets + */ + public int getGadgetCount() + { + return getUtil().getDriver().findElements(By.className("gadget")).size(); + } + + public boolean hasEditButton() + { + return !getDriver().findElementsWithoutWaiting(By.id("tmEdit")).isEmpty(); + } +} diff --git a/application-analytics-test/application-analytics-test-pageobjects/src/main/java/com/xwiki/analytics/test/po/MatomoTestUtils.java b/application-analytics-test/application-analytics-test-pageobjects/src/main/java/com/xwiki/analytics/test/po/MatomoTestUtils.java new file mode 100644 index 0000000..922c795 --- /dev/null +++ b/application-analytics-test/application-analytics-test-pageobjects/src/main/java/com/xwiki/analytics/test/po/MatomoTestUtils.java @@ -0,0 +1,73 @@ +/* + * 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 com.xwiki.analytics.test.po; + +import org.openqa.selenium.By; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.xwiki.test.ui.XWikiWebDriver; + +/** + * Encompass the process of creating a Matomo token using the browser interface provided by Matomo. + */ +public class MatomoTestUtils +{ + private static final String CREDENTIALS = "ADMIN1"; + + private static final String LOGIN_FORM_LOGIN_ID = "login_form_login"; + + private static final String LOGIN_FORM_PASSWORD_ID = "login_form_password"; + + private static final String LOGIN_FORM_SUBMIT_ID = "login_form_submit"; + + private static final String DESCRIPTION_ID = "description"; + + private static final String BTN_CSS_SELECTOR = ".btn"; + + private static final String TAG_NAME_CODE = "code"; + + /** + * Creates a new access token by accessing the Matomo GUI. + * + * @param address The address of the Matomo container. + * @return the newly created token as a string + */ + public static String createToken(String address, XWikiWebDriver driver) + { + driver.get(address + "/index.php?module=UsersManager&action=addNewToken&idSite=1&period=day&date=2023-09-03"); + driver.waitUntilElementIsVisible(By.id(LOGIN_FORM_LOGIN_ID)); + driver.findElement(By.id(LOGIN_FORM_LOGIN_ID)).sendKeys(CREDENTIALS); + driver.waitUntilElementIsVisible(By.id(LOGIN_FORM_PASSWORD_ID)); + driver.findElement(By.id(LOGIN_FORM_PASSWORD_ID)).sendKeys(CREDENTIALS); + driver.waitUntilElementIsVisible(By.id(LOGIN_FORM_SUBMIT_ID)); + driver.findElement(By.id(LOGIN_FORM_SUBMIT_ID)).click(); + driver.waitUntilElementIsVisible(By.id(LOGIN_FORM_PASSWORD_ID)); + driver.findElement(By.id(LOGIN_FORM_PASSWORD_ID)).sendKeys(CREDENTIALS); + driver.waitUntilElementIsVisible(By.id(LOGIN_FORM_SUBMIT_ID)); + driver.findElement(By.id(LOGIN_FORM_SUBMIT_ID)).click(); + // Sometimes the Matomo page loads slower and to avoid a flicker the timeout needs to be increased. + driver.waitUntilCondition(ExpectedConditions.visibilityOfElementLocated(By.id(DESCRIPTION_ID)), 15); + driver.findElement(By.id(DESCRIPTION_ID)).sendKeys("TEST TOKEN"); + driver.waitUntilElementIsVisible(By.cssSelector(BTN_CSS_SELECTOR)); + driver.findElement(By.cssSelector(BTN_CSS_SELECTOR)).click(); + driver.waitUntilElementIsVisible(By.tagName(TAG_NAME_CODE)); + return driver.findElement(By.tagName(TAG_NAME_CODE)).getText(); + } +} + diff --git a/application-analytics-test/application-analytics-test-pageobjects/src/main/java/com/xwiki/analytics/test/po/MostViewedPagesElement.java b/application-analytics-test/application-analytics-test-pageobjects/src/main/java/com/xwiki/analytics/test/po/MostViewedPagesElement.java new file mode 100644 index 0000000..29730e8 --- /dev/null +++ b/application-analytics-test/application-analytics-test-pageobjects/src/main/java/com/xwiki/analytics/test/po/MostViewedPagesElement.java @@ -0,0 +1,63 @@ +/* + * 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 com.xwiki.analytics.test.po; + +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.xwiki.test.ui.po.BaseElement; + +/** + * View for the MostViewedPages macro that lets us interact with the macro. + */ +public class MostViewedPagesElement extends BaseElement +{ + static final private String MODAL_CSS = ".modal-dialog.modal-lg"; + + private WebElement container; + + public MostViewedPagesElement() + { + } + + /*** + * This method first waits for the visibility of an information button, identified by a specific CSS selector. + * Once the information button is visible it selects the tile attribute and returns it. + * @return the description of a macro. + */ + public String getMacroDescription() + { + return container.findElement(By.cssSelector(".analyticsDescription")).getAttribute("title"); + } + + public RowEvolutionModal openModal() + { + RowEvolutionModal modal = new RowEvolutionModal(By.cssSelector(MODAL_CSS)); + modal.openModal(); + return modal; + } + + public void waitUntilReady(String id) + { + getDriver().waitUntilElementIsVisible(By.id(id)); + container = getDriver().findElement(By.id(id)); + } +} diff --git a/application-analytics-test/application-analytics-test-pageobjects/src/main/java/com/xwiki/analytics/test/po/RowEvolutionModal.java b/application-analytics-test/application-analytics-test-pageobjects/src/main/java/com/xwiki/analytics/test/po/RowEvolutionModal.java new file mode 100644 index 0000000..897b39f --- /dev/null +++ b/application-analytics-test/application-analytics-test-pageobjects/src/main/java/com/xwiki/analytics/test/po/RowEvolutionModal.java @@ -0,0 +1,40 @@ +/* + * 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 com.xwiki.analytics.test.po; + +import org.openqa.selenium.By; +import org.xwiki.test.ui.po.BaseModal; + +public class RowEvolutionModal extends BaseModal +{ + private static final String ROW_EVOLUTION_BUTTON_SELECTOR = ".analyticsRowEvolution"; + + public RowEvolutionModal(By selector) + { + super(selector); + } + + public RowEvolutionModal openModal() + { + getDriver().waitUntilElementIsVisible(By.cssSelector(ROW_EVOLUTION_BUTTON_SELECTOR)); + getDriver().findElement(By.cssSelector(ROW_EVOLUTION_BUTTON_SELECTOR)).click(); + return this; + } +} diff --git a/application-analytics-test/pom.xml b/application-analytics-test/pom.xml new file mode 100644 index 0000000..4f5b478 --- /dev/null +++ b/application-analytics-test/pom.xml @@ -0,0 +1,54 @@ + + + + + + 4.0.0 + + com.xwiki.analytics + application-analytics + 1.0-SNAPSHOT + + application-analytics-test + Application Analytics (Pro)- Tests - Parent POM + pom + Application Analytics (Pro) - Tests - Parent POM + + + true + true + + true + + + application-analytics-test-pageobjects + + + + docker + + application-analytics-test-docker + + + + \ No newline at end of file diff --git a/application-analytics-ui/pom.xml b/application-analytics-ui/pom.xml index ef8c845..3fefb9c 100644 --- a/application-analytics-ui/pom.xml +++ b/application-analytics-ui/pom.xml @@ -20,7 +20,8 @@ * 02110-1301 USA, or see the FSF site: http://www.fsf.org. --> - + 4.0.0 com.xwiki.analytics @@ -63,6 +64,50 @@ application-analytics-default ${project.version} + + org.xwiki.platform + xwiki-platform-localization-webjar + ${platform.version} + runtime + + + org.xwiki.platform + xwiki-platform-localization-script + ${platform.version} + + + org.xwiki.platform + xwiki-platform-localization-rest-default + ${platform.version} + runtime + + + org.xwiki.platform + xwiki-platform-dashboard-ui + runtime + ${platform.version} + xar + + + org.xwiki.platform + xwiki-platform-icon-ui + ${platform.version} + runtime + xar + + + org.xwiki.platform + xwiki-platform-uiextension-ui + ${platform.version} + xar + + + org.xwiki.platform + xwiki-platform-icon-rest-api + ${platform.version} + runtime + jar + org.xwiki.contrib application-chartjs-webjar diff --git a/application-analytics-ui/src/main/resources/Analytics/Code/AnalyticsJS.xml b/application-analytics-ui/src/main/resources/Analytics/Code/AnalyticsJS.xml index 1e8de36..9a265f5 100644 --- a/application-analytics-ui/src/main/resources/Analytics/Code/AnalyticsJS.xml +++ b/application-analytics-ui/src/main/resources/Analytics/Code/AnalyticsJS.xml @@ -132,7 +132,7 @@ $('[id^="gadget_"]').each(function () { let hiddenElement = $(this).find('.gadget-content .analytics-description'); if (hiddenElement.length > 0) { - let dataElement = $(`<a class="${icon.cssClass} analyticsTitleMargin"></a>`); + let dataElement = $(`<a class="${icon.cssClass} analyticsDescription analyticsTitleMargin"></a>`); dataElement.attr('title', hiddenElement.data('description')); dataElement.attr('href', hiddenElement.data('url')); $(this).find('.gadget-title').append(dataElement); diff --git a/application-analytics-ui/src/main/resources/Analytics/Code/Macros/RowEvolutionJSON.xml b/application-analytics-ui/src/main/resources/Analytics/Code/Macros/RowEvolutionJSON.xml index a108502..aee77e4 100644 --- a/application-analytics-ui/src/main/resources/Analytics/Code/Macros/RowEvolutionJSON.xml +++ b/application-analytics-ui/src/main/resources/Analytics/Code/Macros/RowEvolutionJSON.xml @@ -37,60 +37,62 @@ xwiki/2.1 true {{velocity}} -#set ($parameters = { - 'period' : $request.period, - 'date' : $request.date, - 'module' : 'API', - 'format' : 'json' -}) -#set ($filters = {}) -#if ($request.macroName == 'MostViewedPages') - #set ($discard = $parameters.put('pageUrl', $request.rowIdentifier)) - #set ($discard = $parameters.put('method', 'Actions.getPageUrl')) -#elseif ($request.macroName == 'PagesFollowingASiteSearch') - #set ($discard = $parameters.put('method', 'Actions.getPageUrlsFollowingSiteSearch')) - #set ($discard = $parameters.put('expanded', '1')) - #set ($discard = $parameters.put('flat', '1')) - #set ($discard = $filters.put('url',$request.rowIdentifier)) -#elseif ($request.macroName == 'SearchCategories') - #set ($discard = $parameters.put('segment', $request.rowIdentifier)) - #set ($discard = $parameters.put('method', 'Actions.getSiteSearchCategories')) -#elseif ($request.macroName == 'SiteSearchKeyword') - #set ($discard = $parameters.put('segment', $request.rowIdentifier)) - #set ($discard = $parameters.put('method', 'Actions.getSiteSearchKeywords')) -#elseif ($request.macroName == 'BrowserEngines') - #set ($discard = $parameters.put('method', 'DevicesDetection.getBrowserEngines')) - #set ($discard = $parameters.put('segment', $request.rowIdentifier)) -#elseif ($request.macroName == 'Browsers') - #set ($discard = $parameters.put('method', 'DevicesDetection.getBrowsers')) - #set ($discard = $parameters.put('segment', $request.rowIdentifier)) -#elseif($request.macroName == 'Configurations') - #set ($discard = $parameters.put('method', 'Resolution.getConfiguration')) - #set ($discard = $parameters.put('segment', $request.rowIdentifier)) -#elseif($request.macroName == 'DeviceBrand') - #set ($discard = $parameters.put('method', 'DevicesDetection.getBrand')) - #set ($discard = $parameters.put('segment', $request.rowIdentifier)) -#elseif($request.macroName == 'DeviceModel') - #set ($discard = $parameters.put('method', 'DevicesDetection.getModel')) - #set ($discard = $parameters.put('segment', $request.rowIdentifier)) -#elseif($request.macroName == 'DeviceType') - #set ($discard = $parameters.put('method', 'DevicesDetection.getType')) - #set ($discard = $parameters.put('segment', $request.rowIdentifier)) -#elseif($request.macroName == 'ScreenResolution') - #set ($discard = $parameters.put('method', 'Resolution.getResolution')) - #set ($discard = $parameters.put('segment', $request.rowIdentifier)) -#elseif($request.macroName == 'OperatingSystemVersions') - #set ($discard = $parameters.put('method', 'DevicesDetection.getOsVersions')) - #set ($discard = $parameters.put('segment', $request.rowIdentifier)) +#if ($xcontext.action == 'get') + #set ($parameters = { + 'period' : $request.period, + 'date' : $request.date, + 'module' : 'API', + 'format' : 'json' + }) + #set ($filters = {}) + #if ($request.macroName == 'MostViewedPages') + #set ($discard = $parameters.put('pageUrl', $request.rowIdentifier)) + #set ($discard = $parameters.put('method', 'Actions.getPageUrl')) + #elseif ($request.macroName == 'PagesFollowingASiteSearch') + #set ($discard = $parameters.put('method', 'Actions.getPageUrlsFollowingSiteSearch')) + #set ($discard = $parameters.put('expanded', '1')) + #set ($discard = $parameters.put('flat', '1')) + #set ($discard = $filters.put('url',$request.rowIdentifier)) + #elseif ($request.macroName == 'SearchCategories') + #set ($discard = $parameters.put('segment', $request.rowIdentifier)) + #set ($discard = $parameters.put('method', 'Actions.getSiteSearchCategories')) + #elseif ($request.macroName == 'SiteSearchKeyword') + #set ($discard = $parameters.put('segment', $request.rowIdentifier)) + #set ($discard = $parameters.put('method', 'Actions.getSiteSearchKeywords')) + #elseif ($request.macroName == 'BrowserEngines') + #set ($discard = $parameters.put('method', 'DevicesDetection.getBrowserEngines')) + #set ($discard = $parameters.put('segment', $request.rowIdentifier)) + #elseif ($request.macroName == 'Browsers') + #set ($discard = $parameters.put('method', 'DevicesDetection.getBrowsers')) + #set ($discard = $parameters.put('segment', $request.rowIdentifier)) + #elseif($request.macroName == 'Configurations') + #set ($discard = $parameters.put('method', 'Resolution.getConfiguration')) + #set ($discard = $parameters.put('segment', $request.rowIdentifier)) + #elseif($request.macroName == 'DeviceBrand') + #set ($discard = $parameters.put('method', 'DevicesDetection.getBrand')) + #set ($discard = $parameters.put('segment', $request.rowIdentifier)) + #elseif($request.macroName == 'DeviceModel') + #set ($discard = $parameters.put('method', 'DevicesDetection.getModel')) + #set ($discard = $parameters.put('segment', $request.rowIdentifier)) + #elseif($request.macroName == 'DeviceType') + #set ($discard = $parameters.put('method', 'DevicesDetection.getType')) + #set ($discard = $parameters.put('segment', $request.rowIdentifier)) + #elseif($request.macroName == 'ScreenResolution') + #set ($discard = $parameters.put('method', 'Resolution.getResolution')) + #set ($discard = $parameters.put('segment', $request.rowIdentifier)) + #elseif($request.macroName == 'OperatingSystemVersions') + #set ($discard = $parameters.put('method', 'DevicesDetection.getOsVersions')) + #set ($discard = $parameters.put('segment', $request.rowIdentifier)) #elseif($request.macroName == 'ExitPages') #set ($discard = $parameters.put('pageUrl', $request.rowIdentifier)) #set ($discard = $parameters.put('method', 'Actions.getPageUrl')) #elseif ($request.macroName == 'EntryPages') #set ($discard = $parameters.put('pageUrl', $request.rowIdentifier)) #set ($discard = $parameters.put('method', 'Actions.getPageUrl')) + #end + #set ($analyticsResult = $services.analytics.makeRequest($parameters, $filters, 'RowEvolution')) + #jsonResponse($analyticsResult) #end -#set ($analyticsResult = $services.analytics.makeRequest($parameters, $filters, 'RowEvolution')) -#jsonResponse($analyticsResult) {{/velocity}} diff --git a/application-analytics-ui/src/main/resources/Analytics/Code/Macros/VelocityMacros.xml b/application-analytics-ui/src/main/resources/Analytics/Code/Macros/VelocityMacros.xml index 3375f84..611cd92 100644 --- a/application-analytics-ui/src/main/resources/Analytics/Code/Macros/VelocityMacros.xml +++ b/application-analytics-ui/src/main/resources/Analytics/Code/Macros/VelocityMacros.xml @@ -119,7 +119,7 @@ #end #macro(analytics_modalRowEvolution $matomoFields $macroName $id) - #set ($requestPageURL = $xwiki.getURL('Analytics.Code.Macros.RowEvolutionJSON')) + #set ($requestPageURL = $xwiki.getURL('Analytics.Code.Macros.RowEvolutionJSON', 'get')) {{html clean=false}} <div class="modal fade analyticsRowEvolutionModal" tabindex="-1" role="dialog" aria-label="chartModalLabel" aria-hidden="true"> @@ -203,7 +203,7 @@ #set ($discard = $xwiki.jsx.use('Analytics.Code.AnalyticsJS')) #else {{html clean="false"}} - <h2><div><span>$escapetool.xml($services.localization.render($nameTranslationKey))</span> <a title="$description" href=$url>$services.icon.renderHTML('info')</a><div></h2> + <h2><div><span>$escapetool.xml($services.localization.render($nameTranslationKey))</span> <a class="analyticsDescription" title="$description" href=$url>$services.icon.renderHTML('info')</a><div></h2> {{/html}} #end #end diff --git a/pom.xml b/pom.xml index 0a60f42..2454622 100644 --- a/pom.xml +++ b/pom.xml @@ -53,4 +53,12 @@ application-analytics-default application-analytics-ui - \ No newline at end of file + + + integration-tests + + application-analytics-test + + + +