diff --git a/.circleci/ci/it-tests.js b/.circleci/ci/it-tests.js index 30ae0a89c8..fb8d416468 100644 --- a/.circleci/ci/it-tests.js +++ b/.circleci/ci/it-tests.js @@ -29,12 +29,17 @@ try { // Connect to QP ci.sh('./qp.sh -v bind --server-hostname localhost --server-port 55555'); + // The core components are already installed in the Cloud SDK + let extras = ''; + if (process.env.AEM == 'classic') { + extras = '--bundle com.adobe.cq:core.wcm.components.all:2.9.0:zip'; + } + // Start CQ ci.sh(`./qp.sh -v start --id author --runmode author --port 4502 --qs-jar /home/circleci/cq/author/cq-quickstart.jar \ --bundle org.apache.sling:org.apache.sling.junit.core:1.0.23:jar \ - --bundle com.adobe.commerce.cif:graphql-client:1.6.0:jar \ - --bundle com.adobe.commerce.cif:magento-graphql:6.0.0-magento235:jar \ - --bundle com.adobe.cq:core.wcm.components.all:2.9.0:zip \ + --bundle com.adobe.commerce.cif:graphql-client:1.6.1:jar \ + --bundle com.adobe.commerce.cif:magento-graphql:6.0.0-magento235:jar ${extras} \ --bundle com.adobe.cq:core.wcm.components.examples.ui.apps:2.9.0:zip \ --bundle com.adobe.cq:core.wcm.components.examples.ui.content:2.9.0:zip \ ${ci.addQpFileDependency(config.modules['core-cif-components-apps'])} \ @@ -45,10 +50,36 @@ try { --vm-options \\\"-Xmx1536m -XX:MaxPermSize=256m -Djava.awt.headless=true -javaagent:${process.env.JACOCO_AGENT}=destfile=crx-quickstart/jacoco-it.exec\\\"`); }); + // Run integration tests + ci.sh(`mvn clean verify -U -B \ + -Ptest-all \ + -Dsling.it.instance.url.1=http://localhost:4502 \ + -Dsling.it.instance.runmode.1=author \ + -Dsling.it.instances=1`); + ci.dir(qpPath, () => { // Stop CQ ci.sh('./qp.sh -v stop --id author'); }); + + // Create coverage reports + const createCoverageReport = () => { + // Executing the integration tests runs also executes unit tests and generates a Jacoco report for them. To + // strictly separate unit test from integration test coverage, we explicitly delete the unit test report first. + ci.sh('rm -rf target/site/jacoco'); + + // Download Jacoco file which is exposed by a webserver running inside the AEM container. + ci.sh('curl -O -f http://localhost:3000/crx-quickstart/jacoco-it.exec'); + + // Generate new report + ci.sh(`mvn -B org.jacoco:jacoco-maven-plugin:${process.env.JACOCO_VERSION}:report -Djacoco.dataFile=jacoco-it.exec`); + + // Upload report to codecov + ci.sh('curl -s https://codecov.io/bash | bash -s -- -c -F integration -f target/site/jacoco/jacoco.xml'); + }; + + ci.dir('bundles/core', createCoverageReport); + ci.dir('examples/bundle', createCoverageReport); } finally { // Always download logs from AEM container ci.sh('mkdir logs'); diff --git a/.circleci/config.yml b/.circleci/config.yml index 53dcf9626c..085f98c215 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,7 +1,7 @@ version: 2.1 orbs: - codecov: codecov/codecov@1.0.5 + codecov: codecov/codecov@1.1.1 common: restore_cache: &restore_cache @@ -20,8 +20,19 @@ common: - run: name: Integration tests command: node .circleci/ci/it-tests.js + - store_test_results: + path: it/http/target/failsafe-reports + # Save test results as artifacts + - store_artifacts: + path: it/http/target/failsafe-reports + # Save AEM logs as artifacts - store_artifacts: path: logs + # Save Jacoco coverage report as artifact + - store_artifacts: + path: bundles/core/target/site/jacoco + - store_artifacts: + path: examples/bundle/target/site/jacoco docker_auth: &docker_auth auth: @@ -60,15 +71,10 @@ jobs: - examples/ui.apps/target/*.zip - examples/ui.content/target/*.zip - store_test_results: - path: bundles/core/target/surefire-reports - - store_artifacts: - path: bundles/core/target/surefire-reports - - store_test_results: - path: examples/bundle/target/surefire-reports + path: test-results - store_artifacts: - path: examples/bundle/target/surefire-reports + path: test-results/junit - codecov/upload: - conf: .circleci/codecov.yml flags: unittests karma: @@ -93,7 +99,6 @@ jobs: - store_artifacts: path: ui.apps/karma-junit - codecov/upload: - conf: .circleci/codecov.yml flags: karma jest: @@ -117,7 +122,6 @@ jobs: - store_artifacts: path: ./react-components/test-results - codecov/upload: - conf: .circleci/codecov.yml flags: jest integration-test-655: @@ -126,6 +130,8 @@ jobs: <<: *docker_auth - image: docker-adobe-cif-release.dr-uw2.adobeitc.com/circleci-aem:6.5.5 <<: *docker_auth + environment: + AEM: classic resource_class: large working_directory: /home/circleci/build <<: *integration_test_steps @@ -158,7 +164,7 @@ jobs: command: | echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> /home/circleci/.npmrc echo $GPG_PRIVATE_KEY | base64 --decode | gpg --batch --import - mvn -B -s /home/circleci/project/.circleci/settings.xml clean deploy -P release-sign-artifacts,adobe-public + mvn -B -s /home/circleci/project/.circleci/settings.xml clean deploy -P release-sign-artifacts,adobe-public,skip-it rm -rf /home/circleci/.gnupg rm -rf /home/circleci/.npmrc diff --git a/examples/ui.apps/pom.xml b/examples/ui.apps/pom.xml index e408e749f0..c973660cff 100644 --- a/examples/ui.apps/pom.xml +++ b/examples/ui.apps/pom.xml @@ -187,7 +187,7 @@ install - ${quickstart.url}/crx/packmgr/service.jsp + ${quickstart.publish.url}/crx/packmgr/service.jsp true diff --git a/examples/ui.content/pom.xml b/examples/ui.content/pom.xml index 85a01647cb..327fb3b922 100644 --- a/examples/ui.content/pom.xml +++ b/examples/ui.content/pom.xml @@ -187,7 +187,7 @@ install - ${quickstart.url}/crx/packmgr/service.jsp + ${quickstart.publish.url}/crx/packmgr/service.jsp true diff --git a/it/http/README.md b/it/http/README.md new file mode 100644 index 0000000000..de14167ebc --- /dev/null +++ b/it/http/README.md @@ -0,0 +1,7 @@ +# Integration tests + +This folder contains integration tests that test all the components based on the sample content of the [CIF components library](../../examples). To execute the tests with a local AEM instance, simply setup and install the CIF components library. Make sure you also install the GraphQL client version >= `1.6.1` so you no longer have to setup HTTPS. + +To execute the tests, simply run `mvn clean verify -Ptest-all` + +You can also execute the tests in your favorite IDE. \ No newline at end of file diff --git a/it/http/pom.xml b/it/http/pom.xml new file mode 100644 index 0000000000..a97b1abe90 --- /dev/null +++ b/it/http/pom.xml @@ -0,0 +1,129 @@ + + + + 4.0.0 + + + com.adobe.commerce.cif + core-cif-components-parent + 1.1.3-SNAPSHOT + ../../parent/pom.xml + + + core-cif-components-it-http + AEM CIF Core Components - Integration Tests + https://github.com/adobe/aem-core-cif-components + + + scm:git:https://github.com/adobe/aem-core-cif-components + scm:git:git@github.com:adobe/aem-core-cif-components.git + https://github.com/adobe/aem-core-cif-components + HEAD + + + Adobe + https://www.adobe.com + + + + The Apache License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + + + + + UTF-8 + UTF-8 + ../../eclipse-formatter.xml + + + + + + net.revelc.code.formatter + formatter-maven-plugin + + + net.revelc.code + impsort-maven-plugin + + + + + + + + test-all + + + + it + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + default-integration-test + + integration-test + + + + **/*IT.java + + + + + default-verify + + verify + + + + + + + + + + + + junit + junit + + + com.adobe.cq + cq-testing-clients-65 + 1.1.1 + + + org.slf4j + slf4j-simple + 1.7.25 + + + diff --git a/it/http/src/test/java/com/adobe/cq/commerce/it/http/CommerceTeaserComponentIT.java b/it/http/src/test/java/com/adobe/cq/commerce/it/http/CommerceTeaserComponentIT.java new file mode 100644 index 0000000000..b474af7e40 --- /dev/null +++ b/it/http/src/test/java/com/adobe/cq/commerce/it/http/CommerceTeaserComponentIT.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * + * Copyright 2020 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + * + ******************************************************************************/ + +package com.adobe.cq.commerce.it.http; + +import org.apache.sling.testing.clients.ClientException; +import org.apache.sling.testing.clients.SlingHttpResponse; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.select.Elements; +import org.junit.Assert; +import org.junit.Test; + +public class CommerceTeaserComponentIT extends CommerceTestBase { + + // Differentiates between the HTML output of the component itself, and the tab displaying the HTML output + private static final String TEASER_SELECTOR = CMP_EXAMPLES_DEMO_SELECTOR + " .teaser "; + + @Test + public void testCommerceTeaserWithSampleData() throws ClientException { + SlingHttpResponse response = adminAuthor.doGet(COMMERCE_LIBRARY_PATH + "/teaser.html", 200); + Document doc = Jsoup.parse(response.getContent()); + + // Check title + Elements elements = doc.select(TEASER_SELECTOR + ".cmp-teaser__title"); + Assert.assertEquals("Get ready for the cold !", elements.first().html()); + + // Check link + elements = doc.select(TEASER_SELECTOR + ".cmp-teaser__action-link"); + Assert.assertEquals("Find out more", elements.first().html()); + } +} diff --git a/it/http/src/test/java/com/adobe/cq/commerce/it/http/CommerceTestBase.java b/it/http/src/test/java/com/adobe/cq/commerce/it/http/CommerceTestBase.java new file mode 100644 index 0000000000..a65cada9f3 --- /dev/null +++ b/it/http/src/test/java/com/adobe/cq/commerce/it/http/CommerceTestBase.java @@ -0,0 +1,164 @@ +/******************************************************************************* + * + * Copyright 2019 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + * + ******************************************************************************/ + +package com.adobe.cq.commerce.it.http; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.TimeoutException; + +import org.apache.sling.testing.clients.ClientException; +import org.apache.sling.testing.clients.SlingHttpResponse; +import org.apache.sling.testing.clients.osgi.OsgiConsoleClient; +import org.apache.sling.testing.clients.util.JsonUtils; +import org.apache.sling.testing.clients.util.poller.Polling; +import org.codehaus.jackson.JsonNode; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Rule; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.adobe.cq.testing.client.CQClient; +import com.adobe.cq.testing.client.CommerceClient; +import com.adobe.cq.testing.junit.rules.CQAuthorClassRule; +import com.adobe.cq.testing.junit.rules.CQRule; + +import static org.apache.http.HttpStatus.SC_MOVED_TEMPORARILY; + +public class CommerceTestBase { + + private static final Logger LOG = LoggerFactory.getLogger(CommerceTestBase.class); + + public static final String GRAPHQL_CLIENT_BUNDLE = "com.adobe.commerce.cif.graphql-client"; + public static final String GRAPHQL_CLIENT_FACTORY_PID = "com.adobe.cq.commerce.graphql.client.impl.GraphqlClientImpl"; + + protected static final String COMMERCE_LIBRARY_PATH = "/content/core-components-examples/library/commerce"; + protected static final String CMP_EXAMPLES_DEMO_SELECTOR = ".cmp-examples-demo__top"; + + private static final String CONFIGURATION_CONSOLE_URL = "/system/console/configMgr"; + + @ClassRule + public static final CQAuthorClassRule cqBaseClassRule = new CQAuthorClassRule(); + + @Rule + public CQRule cqBaseRule = new CQRule(cqBaseClassRule.authorRule); + + protected static CQClient adminAuthor; + + @BeforeClass + public static void init() throws ClientException, InterruptedException, TimeoutException { + adminAuthor = cqBaseClassRule.authorRule.getAdminClient(CommerceClient.class); + + // This configures the GraphQL client for the CIF components library + GraphqlOSGiConfig graphqlOsgiConfig = new GraphqlOSGiConfig() + .withIdentifier("examples") + .withUrl("http://localhost:4502/apps/cif-components-examples/graphql") + .withHttpMethod("GET") + .withAcceptSelfSignedCertificates(true) + .withAllowHttpProtocol(true); + + updateOSGiConfiguration(adminAuthor, graphqlOsgiConfig.build(), GRAPHQL_CLIENT_BUNDLE, GRAPHQL_CLIENT_FACTORY_PID); + updateSlingAuthenticatorOSGiConfig(adminAuthor); + } + + /** + * Fetches the PID of a service based on the factory PID. + * + * @param osgiClient + * @return The PID of the first configuration found for factory PID. + * @throws ClientException + */ + private static String getConfigurationPid(OsgiConsoleClient osgiClient, String factoryPID) throws ClientException { + SlingHttpResponse resp = osgiClient.doGet(CONFIGURATION_CONSOLE_URL + "/*.json"); + JsonNode json = JsonUtils.getJsonNodeFromString(resp.getContent()); + Iterator it = json.getElements(); + while (it.hasNext()) { + JsonNode config = it.next(); + JsonNode factoryId = config.get("factoryPid"); + if (factoryId != null && factoryPID.equals(factoryId.getTextValue())) { + return config.get("pid").getTextValue(); + } + } + return null; + } + + protected static void updateOSGiConfiguration(CQClient client, Map config, String bundle, String factoryPID) + throws ClientException, + TimeoutException, InterruptedException { + final OsgiConsoleClient osgiClient = client.adaptTo(OsgiConsoleClient.class); + Polling polling = new Polling(new Callable() { + @Override + public Boolean call() throws Exception { + try { + String state = osgiClient.getBundleState(bundle); + LOG.info("Bundle {} state is now {}", bundle, state); + Assert.assertEquals("Active", state); + return true; + } catch (AssertionError e) { + return false; + } catch (ClientException cex) { + LOG.error(cex.getMessage(), cex); + return false; + } + } + }); + + // Check that the bundle has started + polling.poll(30000, 1000); + + LOG.info("Creating configuration. {}", config); + String configurationPid = getConfigurationPid(osgiClient, factoryPID); + osgiClient.waitEditConfiguration(30, configurationPid, null, config, SC_MOVED_TEMPORARILY); + + // Wait for bundle to restart + polling.poll(30000, 1000); + + // Wait a bit more so that other bundles can restart + Thread.sleep(2000); + } + + protected static void updateSlingAuthenticatorOSGiConfig(CQClient client) throws InterruptedException, ClientException, + TimeoutException { + + // We keep all the parameters from the default config, we only add the path for the GraphQL servlet + + Map config = new HashMap<>(); + config.put("auth.sudo.cookie", "sling.sudo"); + config.put("auth.sudo.parameter", "sudo"); + config.put("auth.annonymous", "false"); + config.put("sling.auth.requirements", new String[] { + "+/", + "-/libs/granite/core/content/login", + "-/etc.clientlibs", + "-/etc/clientlibs/granite", + "-/libs/dam/remoteassets/content/loginerror", + "-/apps/cif-components-examples/graphql" // We have to add this path so that the GraphQL servlet is reachable + }); + config.put("sling.auth.anonymous.user", ""); + config.put("sling.auth.anonymous.password", "unmodified"); + config.put("auth.http", "preemptive"); + config.put("auth.http.realm", "Sling+(Development)"); + config.put("auth.uri.suffix", "/j_security_check"); + + final OsgiConsoleClient osgiClient = client.adaptTo(OsgiConsoleClient.class); + osgiClient.waitEditConfiguration(30, "org.apache.sling.engine.impl.auth.SlingAuthenticator", null, config, SC_MOVED_TEMPORARILY); + + // Wait a bit more so that other bundles can restart + Thread.sleep(2000); + } +} diff --git a/it/http/src/test/java/com/adobe/cq/commerce/it/http/FeaturedCategoryListComponentIT.java b/it/http/src/test/java/com/adobe/cq/commerce/it/http/FeaturedCategoryListComponentIT.java new file mode 100644 index 0000000000..4888b1e665 --- /dev/null +++ b/it/http/src/test/java/com/adobe/cq/commerce/it/http/FeaturedCategoryListComponentIT.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * + * Copyright 2020 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + * + ******************************************************************************/ + +package com.adobe.cq.commerce.it.http; + +import org.apache.sling.testing.clients.ClientException; +import org.apache.sling.testing.clients.SlingHttpResponse; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.select.Elements; +import org.junit.Assert; +import org.junit.Test; + +public class FeaturedCategoryListComponentIT extends CommerceTestBase { + + // Differentiates between the HTML output of the component itself, and the tab displaying the HTML output + private static final String FEATUREDCATEGORYLIST_SELECTOR = CMP_EXAMPLES_DEMO_SELECTOR + " .featuredcategorylist "; + + @Test + public void testFeaturedCategoryListWithSampleData() throws ClientException { + SlingHttpResponse response = adminAuthor.doGet(COMMERCE_LIBRARY_PATH + "/featuredcategorylist.html", 200); + Document doc = Jsoup.parse(response.getContent()); + + // Check title + Elements elements = doc.select(FEATUREDCATEGORYLIST_SELECTOR + ".cmp-categorylist__title"); + Assert.assertEquals("Jackets for men and women!", elements.first().html()); + + // Check that the components displays 2 categories + elements = doc.select(FEATUREDCATEGORYLIST_SELECTOR + ".cmp-categorylist__content > .cmp-categorylist__anchor"); + Assert.assertEquals(2, elements.size()); + } +} diff --git a/it/http/src/test/java/com/adobe/cq/commerce/it/http/GraphqlOSGiConfig.java b/it/http/src/test/java/com/adobe/cq/commerce/it/http/GraphqlOSGiConfig.java new file mode 100644 index 0000000000..40f9b9f7a6 --- /dev/null +++ b/it/http/src/test/java/com/adobe/cq/commerce/it/http/GraphqlOSGiConfig.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * + * Copyright 2019 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + * + ******************************************************************************/ + +package com.adobe.cq.commerce.it.http; + +import java.util.HashMap; +import java.util.Map; + +/** + * Builds the OSGI config to be updated from the ITs. + */ +public class GraphqlOSGiConfig { + + Map config; + + public GraphqlOSGiConfig() { + config = new HashMap<>(); + } + + public Map build() { + return this.config; + } + + public GraphqlOSGiConfig withIdentifier(String identifier) { + config.put("identifier", identifier); + return this; + } + + public GraphqlOSGiConfig withUrl(String url) { + config.put("url", url); + return this; + } + + public GraphqlOSGiConfig withHttpMethod(String httpMethod) { + config.put("httpMethod", httpMethod); + return this; + } + + public GraphqlOSGiConfig withAcceptSelfSignedCertificates(boolean acceptSelfSignedCertificates) { + config.put("acceptSelfSignedCertificates", Boolean.valueOf(acceptSelfSignedCertificates).toString()); + return this; + } + + public GraphqlOSGiConfig withAllowHttpProtocol(boolean allowHttpProtocol) { + config.put("allowHttpProtocol", Boolean.valueOf(allowHttpProtocol).toString()); + return this; + } +} diff --git a/it/http/src/test/java/com/adobe/cq/commerce/it/http/NavigationComponentIT.java b/it/http/src/test/java/com/adobe/cq/commerce/it/http/NavigationComponentIT.java new file mode 100644 index 0000000000..7fdbc811aa --- /dev/null +++ b/it/http/src/test/java/com/adobe/cq/commerce/it/http/NavigationComponentIT.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * + * Copyright 2020 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + * + ******************************************************************************/ + +package com.adobe.cq.commerce.it.http; + +import org.apache.sling.testing.clients.ClientException; +import org.apache.sling.testing.clients.SlingHttpResponse; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.select.Elements; +import org.junit.Assert; +import org.junit.Test; + +public class NavigationComponentIT extends CommerceTestBase { + + // Differentiates between the HTML output of the component itself, and the tab displaying the HTML output + private static final String NAVIGATION_SELECTOR = CMP_EXAMPLES_DEMO_SELECTOR + " .navigation "; + + @Test + public void testNavigationWithSampleData() throws ClientException { + SlingHttpResponse response = adminAuthor.doGet(COMMERCE_LIBRARY_PATH + "/navigation.html", 200); + Document doc = Jsoup.parse(response.getContent()); + + // Check the number of elements in the navigation menu + Elements elements = doc.select(NAVIGATION_SELECTOR + ".categoryTree__root > .categoryTree__tree > .cmp-navigation__item"); + Assert.assertEquals(9, elements.size()); + } +} diff --git a/it/http/src/test/java/com/adobe/cq/commerce/it/http/ProductCarouselComponentIT.java b/it/http/src/test/java/com/adobe/cq/commerce/it/http/ProductCarouselComponentIT.java new file mode 100644 index 0000000000..66e4aeae17 --- /dev/null +++ b/it/http/src/test/java/com/adobe/cq/commerce/it/http/ProductCarouselComponentIT.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * + * Copyright 2020 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + * + ******************************************************************************/ + +package com.adobe.cq.commerce.it.http; + +import org.apache.sling.testing.clients.ClientException; +import org.apache.sling.testing.clients.SlingHttpResponse; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.select.Elements; +import org.junit.Assert; +import org.junit.Test; + +public class ProductCarouselComponentIT extends CommerceTestBase { + + // Differentiates between the HTML output of the component itself, and the tab displaying the HTML output + private static final String PRODUCTCAROUSEL_SELECTOR = CMP_EXAMPLES_DEMO_SELECTOR + " .productcarousel "; + + @Test + public void testProductCarouselWithSampleData() throws ClientException { + SlingHttpResponse response = adminAuthor.doGet(COMMERCE_LIBRARY_PATH + "/productcarousel.html", 200); + Document doc = Jsoup.parse(response.getContent()); + + // Verify component title + Elements elements = doc.select(PRODUCTCAROUSEL_SELECTOR + ".productcarousel__title"); + Assert.assertEquals("Summer promotions!", elements.first().html()); + + // Check that the components shows 4 products + elements = doc.select(PRODUCTCAROUSEL_SELECTOR + ".productcarousel__cardscontainer > .product__card"); + Assert.assertEquals(4, elements.size()); + } +} diff --git a/it/http/src/test/java/com/adobe/cq/commerce/it/http/ProductComponentIT.java b/it/http/src/test/java/com/adobe/cq/commerce/it/http/ProductComponentIT.java new file mode 100644 index 0000000000..4eb0ed193a --- /dev/null +++ b/it/http/src/test/java/com/adobe/cq/commerce/it/http/ProductComponentIT.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * + * Copyright 2020 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + * + ******************************************************************************/ + +package com.adobe.cq.commerce.it.http; + +import org.apache.sling.testing.clients.ClientException; +import org.apache.sling.testing.clients.SlingHttpResponse; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.select.Elements; +import org.junit.Assert; +import org.junit.Test; + +public class ProductComponentIT extends CommerceTestBase { + + // Differentiates between the HTML output of the component itself, and the tab displaying the HTML output + private static final String PRODUCT_SELECTOR = CMP_EXAMPLES_DEMO_SELECTOR + " .product "; + + @Test + public void testProductPageWithSampleData() throws ClientException { + SlingHttpResponse response = adminAuthor.doGet(COMMERCE_LIBRARY_PATH + "/product.chaz-kangeroo-hoodie.html", 200); + Document doc = Jsoup.parse(response.getContent()); + + // Verify product name + Elements elements = doc.select(PRODUCT_SELECTOR + ".productFullDetail__productName > span"); + Assert.assertEquals("Chaz Kangeroo Hoodie", elements.first().html()); + + // Verify that the section for GroupedProduct is NOT displayed + Assert.assertEquals(0, doc.select(".productFullDetail__groupedProducts").size()); + } + + @Test + public void testProductPageWithSampleDataForGroupedProduct() throws ClientException { + SlingHttpResponse response = adminAuthor.doGet(COMMERCE_LIBRARY_PATH + "/product.set-of-sprite-yoga-straps.html", 200); + Document doc = Jsoup.parse(response.getContent()); + + // Verify product name + Elements elements = doc.select(PRODUCT_SELECTOR + ".productFullDetail__productName > span"); + Assert.assertEquals("Set of Sprite Yoga Straps", elements.first().html()); + + // Verify that the section for GroupedProduct is displayed + Assert.assertEquals(1, doc.select(PRODUCT_SELECTOR + ".productFullDetail__groupedProducts").size()); + } + + @Test + public void testProductPageWithPlaceholderData() throws ClientException { + SlingHttpResponse response = adminAuthor.doGet(COMMERCE_LIBRARY_PATH + "/product.html", 200); + Document doc = Jsoup.parse(response.getContent()); + + // Verify product name + Elements elements = doc.select(PRODUCT_SELECTOR + ".productFullDetail__productName > span"); + Assert.assertEquals("Product name", elements.first().html()); + } +} diff --git a/it/http/src/test/java/com/adobe/cq/commerce/it/http/ProductListComponentIT.java b/it/http/src/test/java/com/adobe/cq/commerce/it/http/ProductListComponentIT.java new file mode 100644 index 0000000000..8429eb6b04 --- /dev/null +++ b/it/http/src/test/java/com/adobe/cq/commerce/it/http/ProductListComponentIT.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * + * Copyright 2020 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + * + ******************************************************************************/ + +package com.adobe.cq.commerce.it.http; + +import org.apache.sling.testing.clients.ClientException; +import org.apache.sling.testing.clients.SlingHttpResponse; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.select.Elements; +import org.junit.Assert; +import org.junit.Test; + +public class ProductListComponentIT extends CommerceTestBase { + + // Differentiates between the HTML output of the component itself, and the tab displaying the HTML output + private static final String PRODUCTLIST_SELECTOR = CMP_EXAMPLES_DEMO_SELECTOR + " .productlist "; + + @Test + public void testProductListPageWithSampleData() throws ClientException { + SlingHttpResponse response = adminAuthor.doGet(COMMERCE_LIBRARY_PATH + "/productlist.1.html", 200); + Document doc = Jsoup.parse(response.getContent()); + + // Verify category name + Elements elements = doc.select(PRODUCTLIST_SELECTOR + ".category__categoryTitle"); + Assert.assertEquals("Outdoor Collection", elements.first().html()); + + // Check that search filters are displayed + elements = doc.select(PRODUCTLIST_SELECTOR + ".search__filters"); + Assert.assertEquals(1, elements.size()); + + // Check that the 6 products are displayed on the first page + elements = doc.select(PRODUCTLIST_SELECTOR + ".gallery__items > .item__root"); + Assert.assertEquals(6, elements.size()); + } + + @Test + public void testProductListPageWithPlaceholderData() throws ClientException { + SlingHttpResponse response = adminAuthor.doGet(COMMERCE_LIBRARY_PATH + "/productlist.html", 200); + Document doc = Jsoup.parse(response.getContent()); + + // Verify category name + Elements elements = doc.select(PRODUCTLIST_SELECTOR + ".category__categoryTitle"); + Assert.assertEquals("Category name", elements.first().html()); + + // Check that search filters are NOT displayed + elements = doc.select(PRODUCTLIST_SELECTOR + ".search__filters"); + Assert.assertTrue(elements.isEmpty()); + + // Check that the 6 products are displayed on the first page + elements = doc.select(PRODUCTLIST_SELECTOR + ".gallery__items > .item__root"); + Assert.assertEquals(6, elements.size()); + } +} diff --git a/it/http/src/test/java/com/adobe/cq/commerce/it/http/ProductTeaserComponentIT.java b/it/http/src/test/java/com/adobe/cq/commerce/it/http/ProductTeaserComponentIT.java new file mode 100644 index 0000000000..a301cc5fd4 --- /dev/null +++ b/it/http/src/test/java/com/adobe/cq/commerce/it/http/ProductTeaserComponentIT.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * + * Copyright 2020 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + * + ******************************************************************************/ + +package com.adobe.cq.commerce.it.http; + +import org.apache.sling.testing.clients.ClientException; +import org.apache.sling.testing.clients.SlingHttpResponse; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.select.Elements; +import org.junit.Assert; +import org.junit.Test; + +public class ProductTeaserComponentIT extends CommerceTestBase { + + // Differentiates between the HTML output of the component itself, and the tab displaying the HTML output + private static final String PRODUCTTEASER_SELECTOR = CMP_EXAMPLES_DEMO_SELECTOR + " .productteaser "; + + @Test + public void testProductTeaserWithSampleData() throws ClientException { + SlingHttpResponse response = adminAuthor.doGet(COMMERCE_LIBRARY_PATH + "/productteaser.html", 200); + Document doc = Jsoup.parse(response.getContent()); + + // Verify product name + Elements elements = doc.select(PRODUCTTEASER_SELECTOR + ".item__name > span"); + Assert.assertEquals("Summit Watch", elements.first().html()); + } +} diff --git a/it/http/src/test/java/com/adobe/cq/commerce/it/http/RelatedProductsComponentIT.java b/it/http/src/test/java/com/adobe/cq/commerce/it/http/RelatedProductsComponentIT.java new file mode 100644 index 0000000000..d3562a6cd8 --- /dev/null +++ b/it/http/src/test/java/com/adobe/cq/commerce/it/http/RelatedProductsComponentIT.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * + * Copyright 2020 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + * + ******************************************************************************/ + +package com.adobe.cq.commerce.it.http; + +import org.apache.sling.testing.clients.ClientException; +import org.apache.sling.testing.clients.SlingHttpResponse; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.select.Elements; +import org.junit.Assert; +import org.junit.Test; + +public class RelatedProductsComponentIT extends CommerceTestBase { + + // Differentiates between the HTML output of the component itself, and the tab displaying the HTML output + private static final String RELATEDPRODUCTS_SELECTOR = CMP_EXAMPLES_DEMO_SELECTOR + " .relatedproducts "; + + @Test + public void testRelatedProductsWithSampleData() throws ClientException { + SlingHttpResponse response = adminAuthor.doGet(COMMERCE_LIBRARY_PATH + "/relatedproducts.html", 200); + Document doc = Jsoup.parse(response.getContent()); + + // Verify component title + Elements elements = doc.select(RELATEDPRODUCTS_SELECTOR + ".productcarousel__title"); + Assert.assertEquals("Upsells for the Summit Backback!", elements.first().html()); + + // Check that the components shows 2 products + elements = doc.select(RELATEDPRODUCTS_SELECTOR + ".productcarousel__cardscontainer > .product__card"); + Assert.assertEquals(2, elements.size()); + } +} diff --git a/it/http/src/test/java/com/adobe/cq/commerce/it/http/SearchResultsComponentIT.java b/it/http/src/test/java/com/adobe/cq/commerce/it/http/SearchResultsComponentIT.java new file mode 100644 index 0000000000..5b32ebd0e3 --- /dev/null +++ b/it/http/src/test/java/com/adobe/cq/commerce/it/http/SearchResultsComponentIT.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * + * Copyright 2020 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + * + ******************************************************************************/ + +package com.adobe.cq.commerce.it.http; + +import org.apache.sling.testing.clients.ClientException; +import org.apache.sling.testing.clients.SlingHttpResponse; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.select.Elements; +import org.junit.Assert; +import org.junit.Test; + +public class SearchResultsComponentIT extends CommerceTestBase { + + // Differentiates between the HTML output of the component itself, and the tab displaying the HTML output + private static final String SEARCHRESULTS_SELECTOR = CMP_EXAMPLES_DEMO_SELECTOR + " .searchresults "; + + @Test + public void testSearchResultsWithSampleData() throws ClientException { + SlingHttpResponse response = adminAuthor.doGet(COMMERCE_LIBRARY_PATH + "/search.html?search_query=test", 200); + Document doc = Jsoup.parse(response.getContent()); + + // Check that search filters are displayed + Elements elements = doc.select(SEARCHRESULTS_SELECTOR + ".search__filters"); + Assert.assertEquals(1, elements.size()); + + // Check that the 6 products are displayed on the first page + elements = doc.select(SEARCHRESULTS_SELECTOR + ".gallery__items > .item__root"); + Assert.assertEquals(6, elements.size()); + } + + @Test + public void testSearchResultsWithoutSearchQuery() throws ClientException { + SlingHttpResponse response = adminAuthor.doGet(COMMERCE_LIBRARY_PATH + "/search.html", 200); + Document doc = Jsoup.parse(response.getContent()); + + // Check that the search doesn't display any product + Elements elements = doc.select(SEARCHRESULTS_SELECTOR + ".category__root p"); + Assert.assertEquals("No products to display.", elements.first().html()); + } +} diff --git a/parent/pom.xml b/parent/pom.xml index 00fa8b7ede..1f325123e8 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -426,7 +426,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 2.18.1 + 3.0.0-M5 diff --git a/pom.xml b/pom.xml index 8fa11036f8..cfa189ed8b 100644 --- a/pom.xml +++ b/pom.xml @@ -43,21 +43,22 @@ react-components ui.apps bundles/core + examples all - + - examples-library + integration-tests - !skip-examples + !skip-it - examples + it/http