Skip to content

Commit

Permalink
Merge pull request #823 from adobe/masterTo650
Browse files Browse the repository at this point in the history
Master to650
  • Loading branch information
sakshi-arora1 authored Oct 20, 2023
2 parents 575ab2e + 2875cfa commit 155b965
Show file tree
Hide file tree
Showing 497 changed files with 21,082 additions and 3,461 deletions.
75 changes: 41 additions & 34 deletions .circleci/ci/accessibility-axe.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

const fs = require('fs');
const ci = new (require('./ci.js'))();
const AxeBuilder = require('@axe-core/webdriverjs');
const { AxeBuilder } = require('@axe-core/webdriverjs');
const WebDriver = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const { createHtmlReport } = require('axe-html-reporter');
Expand All @@ -27,7 +27,7 @@ const calculateAccessibility = async () => {

const options = new chrome.Options();
const driver = new WebDriver.Builder().forBrowser('chrome').setChromeOptions(options).build();
const ACCESSIBILITY_COLLATERAL_URL = "http://localhost:4502/content/dam/formsanddocuments/core-components-it/samples/wizard/repeatability/jcr:content?wcmmode=disabled"
const ACCESSIBILITY_COLLATERAL_URL = "http://localhost:4502/content/dam/formsanddocuments/core-components-it/samples/accessibility/jcr:content?wcmmode=disabled"
const aemUsername = ci.sh('mvn --file ui.tests help:evaluate -Dexpression=AEM_AUTHOR_USERNAME -q -DforceStdout', true);
const aemPassword = ci.sh('mvn --file ui.tests help:evaluate -Dexpression=AEM_AUTHOR_PASSWORD -q -DforceStdout', true);

Expand Down Expand Up @@ -60,53 +60,60 @@ const calculateAccessibility = async () => {
},
});
fs.writeFileSync('accessibility-report.html', reportHTML);
// adding node index to prevent multiple github comments in PR
let nodeIndex = 0;
if (process.env.CIRCLE_NODE_INDEX !== undefined) {
nodeIndex = process.env.CIRCLE_NODE_INDEX;
}
console.log('node index ', nodeIndex);

if ((process.env.AEM === "addon" || process.env.AEM === "classic") && nodeIndex == 0) {

if (results.violations.length > 0) {
console.log(getAccessibilityViolationsTable(results.violations))
await ci.postCommentToGitHubFromCI(getAccessibilityViolationsTable(results.violations));
// impact can be 'critical', 'serious', 'moderate', 'minor', 'unknown'
if (
results.violations.some(
(violation) => ["critical", "serious", "moderate"].includes(violation.impact) &&
!accessibilityConfig.accessibilityExceptionList.includes(violation.id)
)
) {
console.log("Error: Accessibility violations found, please refer the report under artifacts to fix the same!");
await ci.postCommentToGitHubFromCI("Error: Accessibility violations found, please refer the report under artifacts, inside circleCI PR, to fix the same!");
process.exit(1); // fail pipeline
}

console.log("results.violations--->>>", results.violations);
}

if (results.violations.length > 0) {
getAccessibilityViolationsTable(results.violations)
// impact can be 'critical', 'serious', 'moderate', 'minor', 'unknown'
if (
results.violations.some(
(violation) =>
["critical", "serious", "moderate"].includes(violation.impact) &&
!accessibilityConfig.accessibilityExceptionList.includes(violation.id)
) &&
process.env.AEM === "addon"
) {
console.log(
"Error: Accessibility violations found, please refer the report under artifacts to fix the same!"
);
await ci.postCommentToGitHubFromCI("Error: Accessibility violations found, please refer the report under artifacts, inside circleCI PR, to fix the same!");
process.exit(1); // fail pipeline
}

console.log("results.violations--->>>", results.violations);
}

}
catch (e) {
console.log("Some error occured in calculating accessibility", e)
}
}

const getAccessibilityViolationsTable = (violations) => {
const printRow = (id, description, impact) => {
console.log(
`| ${id + " ".repeat(20 - id.length)} | ${
description + " ".repeat(100 - description.length)
} | ${impact + " ".repeat(20 - impact.length)} |`
);
const printRow = (id, impact) => {
return `| ${id + " ".repeat(30 - id.length)} | ${
impact + " ".repeat(25 - impact.length)
} |\n`;
};

const printDashedLine = () => {
console.log(`| ${"-".repeat(22)}|${"-".repeat(102)}|${"-".repeat(22)}|`);
return `| ${"-".repeat(30)} | ${"-".repeat(25)} |\n`;
};

console.log("\n\n### Accessibility Violations Found\n");
printDashedLine();
printRow("Id", "Description", "Impact");
printDashedLine();
let table = "";
table += "\n\n### Accessibility Violations Found\n";
table += `| Id | Impact |\n`;
table += printDashedLine();
violations.forEach((violation) => {
printRow(violation.id, violation.description, violation.impact);
printDashedLine();
table += printRow(violation.id, violation.impact);
});
return table;
};

calculateAccessibility()
7 changes: 1 addition & 6 deletions .circleci/ci/accessibilityConfig.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
{
"accessibilityExceptionList": [
"label",
"landmark-one-main",
"page-has-heading-one",
"region"
]
"accessibilityExceptionList": ["landmark-one-main", "label-title-only", "region"]
}
5 changes: 4 additions & 1 deletion .circleci/ci/ci.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,13 @@ module.exports = class CI {
return JSON.parse(configuration);
}

addQpFileDependency(module) {
addQpFileDependency(module, cloud = false) {
let output = '--install-file ';

let filename = `${module.artifactId}-${module.version}`;
if (cloud) {
filename += '-cloud';
}
if (module.packaging == 'content-package') {
filename += '.zip';
} else if (module.packaging == 'bundle') {
Expand Down
35 changes: 23 additions & 12 deletions .circleci/ci/it-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const config = ci.restoreConfiguration();
console.log(config);
const qpPath = '/home/circleci/cq';
const buildPath = '/home/circleci/build';
const { TYPE, BROWSER, AEM, PRERELEASE } = process.env;
const { TYPE, BROWSER, AEM, PRERELEASE, FT } = process.env;
const classicFormAddonVersion = 'LATEST';
const classicFormReleasedAddonVersion = '6.0.1016';

Expand Down Expand Up @@ -67,16 +67,24 @@ try {
}
}

if (FT === 'true') {
// add feature toggle impl bundle to check FT on cloud ready or release/650 instance
extras += ` --install-file ${buildPath}/it/core/src/main/resources/com.adobe.granite.toggle.impl.dev-1.1.2.jar`;
}

// Set an environment variable indicating test was executed
// this is used in case of re-run failed test scenario
ci.sh("sed -i 's/false/true/' /home/circleci/build/TEST_EXECUTION_STATUS.txt")
// 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.cq:core.wcm.components.examples.ui.config:${wcmVersion}:zip \
--bundle com.adobe.cq:core.wcm.components.examples.ui.apps:${wcmVersion}:zip \
--bundle com.adobe.cq:core.wcm.components.examples.ui.content:${wcmVersion}:zip \
${extras} \
${ci.addQpFileDependency(config.modules['core-forms-components-apps'])} \
${ci.addQpFileDependency(config.modules['core-forms-components-af-apps'])} \
${ci.addQpFileDependency(config.modules['core-forms-components-core'])} \
${ci.addQpFileDependency(config.modules['core-forms-components-apps'] /*, isLatestAddon ? true : false */)} \
${ci.addQpFileDependency(config.modules['core-forms-components-af-apps'] /*, isLatestAddon ? true : false */)} \
${ci.addQpFileDependency(config.modules['core-forms-components-core'])} \\
${ci.addQpFileDependency(config.modules['core-forms-components-af-core'])} \
${ci.addQpFileDependency(config.modules['core-forms-components-examples-apps'])} \
${ci.addQpFileDependency(config.modules['core-forms-components-examples-content'])} \
Expand All @@ -88,13 +96,15 @@ try {
--vm-options \\\"-Xmx4096m -XX:MaxPermSize=1024m -Djava.awt.headless=true -javaagent:${process.env.JACOCO_AGENT}=destfile=crx-quickstart/jacoco-it.exec\\\" \
${preleaseOpts}`);

if (AEM === 'classic' || AEM === 'classic-latest') {
// add a sleep for 5 mins, add-on takes times to come up
ci.sh(`sleep 5m`);
// restart the AEM insatnce
ci.sh(`./qp.sh stop --id author`);
ci.sh(`./qp.sh start --id author`);
}
if (AEM === 'classic' || AEM === 'classic-latest') {
// add a sleep for 10 mins, add-on takes times to come up
ci.sh(`sleep 10m`);
// restart the AEM insatnce
ci.sh(`./qp.sh stop --id author`);
ci.sh(`./qp.sh start --id author`);
// add a sleep for 5 mins, add-on takes times to come up
ci.sh(`sleep 5m`);
}
});

// Run integration tests
Expand Down Expand Up @@ -145,7 +155,8 @@ try {
ci.dir('bundles/core', createCoverageReport);
ci.dir('examples/core', createCoverageReport);

} finally { // Always download logs from AEM container
} finally {
// Always download logs from AEM container
ci.sh('mkdir logs');
ci.dir('logs', () => {
// A webserver running inside the AEM container exposes the logs folder, so we can download log files as needed.
Expand Down
63 changes: 45 additions & 18 deletions .circleci/ci/lighthouse.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,12 @@
const fs = require('fs');
const ci = new (require('./ci.js'))();


const checkLightHouse = async () => {

const aemUsername = ci.sh('mvn --file ui.tests help:evaluate -Dexpression=AEM_AUTHOR_USERNAME -q -DforceStdout', true);
const aemPassword = ci.sh('mvn --file ui.tests help:evaluate -Dexpression=AEM_AUTHOR_PASSWORD -q -DforceStdout', true);

const lighthouse = await import('lighthouse')
const {default: LHDesktopConfig} = await import('lighthouse/core/config/desktop-config.js')
const chromeLauncher = await import('chrome-launcher')
const chrome = await chromeLauncher.launch({chromeFlags: ['--headless']});
const options = {
Expand All @@ -40,37 +39,65 @@ const checkLightHouse = async () => {
};
const lighthouseConfig = JSON.parse(fs.readFileSync('/home/circleci/build/.circleci/ci/lighthouseConfig.json'))

const runnerResult = await lighthouse.default(lighthouseConfig.urls[0], options);
// `.report` is the HTML report as a string

const reportHtml = runnerResult.report;
console.log('Report is done for', runnerResult.lhr.finalDisplayedUrl);
console.log(getCommentText(runnerResult.lhr.categories))

if(process.env.AEM === "addon"){ // posting lighthouse scores only in case of AEM is addon
await ci.postCommentToGitHubFromCI(getCommentText(runnerResult.lhr.categories))
const desktopResult = await computeMedianScores(lighthouseConfig.urls[0], options, LHDesktopConfig) // Running lighthouse for desktop
console.log('Lighthouse Report for desktop generated', desktopResult.lhr.finalDisplayedUrl);
console.log(getCommentText(desktopResult.lhr.categories, 'desktop'))
const desktopReportHtml = desktopResult.report;

const mobileResult = await computeMedianScores(lighthouseConfig.urls[0], options) // by default lighthouse scores are computed for mobile device
console.log('Lighthouse Report for desktop generated', mobileResult.lhr.finalDisplayedUrl);
console.log(getCommentText(mobileResult.lhr.categories, 'mobile'))
const mobileReportHtml = mobileResult.report;
// adding node index to prevent multiple github comments in PR
let nodeIndex = 0;
if (process.env.CIRCLE_NODE_INDEX !== undefined) {
nodeIndex = process.env.CIRCLE_NODE_INDEX;
}
console.log('node index ', nodeIndex);
if((process.env.AEM === "addon" || process.env.AEM === "classic") && nodeIndex == 0){ // posting lighthouse scores only in case of AEM is addon
await ci.postCommentToGitHubFromCI(getCommentText(desktopResult.lhr.categories, 'desktop'))
await ci.postCommentToGitHubFromCI(getCommentText(mobileResult.lhr.categories, 'mobile'))
}
ci.sh('mkdir artifacts');
ci.dir("artifacts", () => {
fs.writeFileSync('LigthouseReport.html', reportHtml);
fs.writeFileSync('DesktopLigthouseReport.html', desktopReportHtml);
fs.writeFileSync('MobileLigthouseReport.html', mobileReportHtml);
});


const thresholdResults = checkThresholds(runnerResult.lhr.categories, lighthouseConfig)
const thresholdResults = checkThresholds(mobileResult.lhr.categories, lighthouseConfig) // using mobile lighthouse scores as these are usually lower
console.log("thresholdResults -->>>> ", thresholdResults)
if(!thresholdResults.isThresholdPass && process.env.AEM === "addon"){
console.log("Error: Lighthouse score for aem-core-forms-components, below the thresholds")
if(!thresholdResults.isThresholdPass && (process.env.AEM === "addon" || process.env.AEM === "classic") && nodeIndex == 0){
console.log("Error: Lighthouse score for aem-core-forms-components, below the thresholds");
await ci.postCommentToGitHubFromCI("Error: Lighthouse score for aem-core-forms-components, below the thresholds, check reports under artifacts in CircleCI")
process.exit(1);
}
else if(thresholdResults.updateLighthouseConfig && ['master', 'dev', 'release/650'].includes(process.env.CIRCLE_BRANCH) && process.env.AEM === "addon"){ // only execute if branch name is 'master'
writeObjLighthouseConfig(runnerResult.lhr.categories, lighthouseConfig)
writeObjLighthouseConfig(mobileResult.lhr.categories, lighthouseConfig)
}
await chrome.kill();
}

const getCommentText = (resultCategories) => {
const commentText = `### Lighthouse scores\n\n| | Performance | Accessibility | Best-Practices | SEO |\n| ------ | ----------- | ------------- | -------------- | --- |\n| Scores | ${resultCategories.performance.score*100} | ${resultCategories.accessibility.score*100} | ${resultCategories['best-practices'].score*100} | ${resultCategories.seo.score*100} |`
const computeMedianScores = async (url, options, config) => {
const {default:lighthouse} = await import('lighthouse');
const {computeMedianRun} = await import('lighthouse/core/lib/median-run.js');
const lhrs = [], results = [];
for(let i=0; i<5; i++) {
try {
const result = await lighthouse(url, options, config);
results.push(result);
lhrs.push(result.lhr);
} catch (e) {
console.log(e)
}
}
const median = computeMedianRun(lhrs);
const result = results[lhrs.indexOf(median)]
return result;
}

const getCommentText = (resultCategories, preset) => {
const commentText = `### Lighthouse scores (${preset})\n\n| | Performance | Accessibility | Best-Practices | SEO |\n| ------ | ----------- | ------------- | -------------- | --- |\n| Scores | ${resultCategories.performance.score*100} | ${resultCategories.accessibility.score*100} | ${resultCategories['best-practices'].score*100} | ${resultCategories.seo.score*100} |`
return commentText
}

Expand Down
6 changes: 3 additions & 3 deletions .circleci/ci/lighthouseConfig.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
{
"urls": [
"http://localhost:4502/content/dam/formsanddocuments/core-components-it/samples/wizard/repeatability/jcr:content?wcmmode=disabled"
"http://localhost:4502/content/dam/formsanddocuments/core-components-it/samples/accessibility/jcr:content?wcmmode=disabled"
],
"requiredScores": [
{
"performance": 80,
"accessibility": 90,
"accessibility": 100,
"bestPractices": 100,
"seo": 70
},
{
"performance": 85,
"accessibility": 95,
"accessibility": 100,
"bestPractices": 100,
"seo": 75
}
Expand Down
Loading

0 comments on commit 155b965

Please sign in to comment.