Skip to content

Commit

Permalink
Merge pull request Accenture#32 from ashvinappi/release_3.5bis
Browse files Browse the repository at this point in the history
version 3.6
  • Loading branch information
sboudaya authored Jun 4, 2024
2 parents e2a9981 + 0c76ede commit 0f9378d
Show file tree
Hide file tree
Showing 23 changed files with 147 additions and 114 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/publish-docker-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: type=raw,value=3.5
tags: type=raw,value=3.6
# This step uses the `docker/build-push-action` action to build the image, based on your repository's `Dockerfile`. If the build succeeds, it pushes the image to GitHub Packages.
# It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see "[Usage](https://github.com/docker/build-push-action#usage)" in the README of the `docker/build-push-action` repository.
# It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step.
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## Version 3.6 , 04/06/2024

### Changed

- User flow : Bug fix, ability to add a user flow with CSS selectors for authentication
- Proxy : Bug fix in string to object cast
- Swagger.js : Documentation updated
- USER GUIDE updated for authentication

---

## Version 3.5 , 18/03/2024

### Added
Expand Down
6 changes: 3 additions & 3 deletions EcoSonar-API/dataBase/projectsRepository.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const ProjectsRepository = function () {
*/
this.createProcedure = function (projectName, procedure) {
return new Promise((resolve, reject) => {
projects.create({ projectName: { $eq: projectName }, procedure })
projects.create({ projectName, procedure })
.then(() => { resolve() })
.catch((error) => {
console.error('\x1b[31m%s\x1b[0m', error)
Expand Down Expand Up @@ -50,7 +50,7 @@ const ProjectsRepository = function () {
this.createLoginConfiguration = async function (projectName, loginCredentials) {
const loginMap = (loginCredentials !== undefined && loginCredentials !== null) ? new Map(Object.entries(loginCredentials)) : {}
return new Promise((resolve, reject) => {
projects.create({ projectName: { $eq: projectName }, login: loginMap })
projects.create({ projectName }, { login: loginMap })
.then(() => { resolve() })
.catch((error) => {
console.error('\x1b[31m%s\x1b[0m', error)
Expand All @@ -66,7 +66,7 @@ const ProjectsRepository = function () {
*/
this.createProxyConfiguration = async function (projectName, proxy) {
return new Promise((resolve, reject) => {
projects.create({ projectName: { $eq: projectName }, proxy })
projects.create({ projectName, proxy })
.then(() => { resolve() })
.catch((error) => {
console.error('\x1b[31m%s\x1b[0m', error)
Expand Down
8 changes: 4 additions & 4 deletions EcoSonar-API/routes/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,10 +231,10 @@ app.delete('/api/delete', asyncMiddleware(async (req, res, _next) => {
* properties:
* authentication_url:
* type: string
* steps:
* type: array
* items:
* type: object
* username:
* type: string
* password:
* type: string
* responses:
* 201:
* description: Success.
Expand Down
1 change: 1 addition & 0 deletions EcoSonar-API/services/W3C/w3cAnalysis.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ W3cAnalysis.prototype.w3cAnalysisLocal = async function (urlsList, projectName,
} catch (error) {
console.error('\x1b[31m%s\x1b[0m', error)
} finally {
console.log('Closing browser for w3cAnalysis');
await browser.close()
}
}
Expand Down
7 changes: 6 additions & 1 deletion EcoSonar-API/services/analysisService.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,14 @@ function formatAuditsToBeSaved (reports, urlProjectList) {
if (lighthouseReport?.runtimeError === undefined) {
const formattedLighthouseMetrics = formatLighthouseMetrics.formatLighthouseMetrics(lighthouseReport)
const urlProjectAudited = urlProjectList.filter((urlProject) => urlProject.urlName === lighthouseReport.url)
let urlProjectAuditedKey = 0;
if (urlProjectAudited.length !== 0) {
urlProjectAuditedKey = urlProjectAudited[0].idKey;
}

const lighthouseAudit = {
idLighthouseAnalysis: uniqid(),
idUrlLighthouse: urlProjectAudited[0].idKey,
idUrlLighthouse: urlProjectAuditedKey,
dateLighthouseAnalysis: date,
performance: formattedLighthouseMetrics.performance,
accessibility: formattedLighthouseMetrics.accessibility,
Expand Down
42 changes: 23 additions & 19 deletions EcoSonar-API/services/format/formatLighthouseBestPractices.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,18 @@ FormatLighthouseBestPractices.prototype.formatAccessibility = function (report)
const formattedReports = {}

for (const element in accessibilityBestPractices) {
const score = report.audits[accessibilityBestPractices[element]].score
const scoreDisplayMode = report.audits[accessibilityBestPractices[element]].scoreDisplayMode
let displayValue = report.audits[accessibilityBestPractices[element]].displayValue
const items = (report.audits[accessibilityBestPractices[element]].details !== undefined) ? report.audits[accessibilityBestPractices[element]].details.items : []
if (scoreDisplayMode === 'binary' && (displayValue === 0 || displayValue === undefined)) {
displayValue = items.length
} else if (displayValue === undefined) {
displayValue = 0
if (report.audits[accessibilityBestPractices[element]] !== undefined) {
const score = report.audits[accessibilityBestPractices[element]].score
const scoreDisplayMode = report.audits[accessibilityBestPractices[element]].scoreDisplayMode
let displayValue = report.audits[accessibilityBestPractices[element]].displayValue
const items = (report.audits[accessibilityBestPractices[element]].details !== undefined) ? report.audits[accessibilityBestPractices[element]].details.items : []
if (scoreDisplayMode === 'binary' && (displayValue === 0 || displayValue === undefined)) {
displayValue = items.length
} else if (displayValue === undefined) {
displayValue = 0
}
formattedReports[element] = { score: score * 100, scoreDisplayMode, description: items, auditedMetric: displayValue, url: report.finalUrl }
}
formattedReports[element] = { score: score * 100, scoreDisplayMode, description: items, auditedMetric: displayValue, url: report.finalUrl }
}
return { ...formattedReports, url: report.url }
}
Expand All @@ -48,16 +50,18 @@ FormatLighthouseBestPractices.prototype.formatPerformance = function (report) {
const formattedReports = {}
for (const element in performanceBestPractices) {
try {
const score = report.audits[performanceBestPractices[element]].score ?? 0
const scoreDisplayMode = report.audits[performanceBestPractices[element]].scoreDisplayMode ?? null
const items = (report.audits[performanceBestPractices[element]].details !== undefined) ? report.audits[performanceBestPractices[element]].details.items : []
let displayValue = report.audits[performanceBestPractices[element]].displayValue ?? null
if (displayValue) {
displayValue = Number(displayValue.replace(',', '').match(reg)[0])
} else {
displayValue = 0
}
formattedReports[element] = { score: score * 100, scoreDisplayMode, description: items, auditedMetric: displayValue }
if (report.audits[performanceBestPractices[element]] !== undefined) {
const score = report.audits[performanceBestPractices[element]].score ?? 0
const scoreDisplayMode = report.audits[performanceBestPractices[element]].scoreDisplayMode ?? null
const items = (report.audits[performanceBestPractices[element]].details !== undefined) ? report.audits[performanceBestPractices[element]].details.items : []
let displayValue = report.audits[performanceBestPractices[element]].displayValue ?? null
if (displayValue) {
displayValue = Number(displayValue.replace(',', '').match(reg)[0])
} else {
displayValue = 0
}
formattedReports[element] = { score: score * 100, scoreDisplayMode, description: items, auditedMetric: displayValue }
}
} catch (error) {
console.error('error for url ' + report.url + ' on element ' + element)
console.error(error)
Expand Down
22 changes: 11 additions & 11 deletions EcoSonar-API/services/format/formatLighthouseMetrics.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ FormatLighthouseMetrics.prototype.formatLighthouseMetrics = function (reports) {
for (const element in lighthouseMetrics) {
try {
let score, complianceLevel, displayValue
if (element === 'performance' || element === 'accessibility') {
score = Math.trunc(reports.categories[lighthouseMetrics[element]].score * 100)
complianceLevel = element === 'performance' ? formatCompliance.getEcodesignGrade(Math.trunc(reports.categories[lighthouseMetrics[element]].score * 100)) : formatCompliance.getAccessibilityGrade(Math.trunc(reports.categories[lighthouseMetrics[element]].score * 100))
formattedReports[element] = { score, complianceLevel }
} else {
score = Math.trunc(reports.audits[lighthouseMetrics[element]].score * 100)
displayValue = reports.audits[lighthouseMetrics[element]].displayValue
displayValue = displayValue ? Number(displayValue.replace(',', '').match(reg)[0]) : 0
complianceLevel = formatCompliance.getEcodesignGrade(Math.trunc(reports.audits[lighthouseMetrics[element]].score * 100))
formattedReports[element] = { score, displayValue, complianceLevel }
}
if (element === 'performance' || element === 'accessibility') {
score = Math.trunc(reports.categories[lighthouseMetrics[element]].score * 100)
complianceLevel = element === 'performance' ? formatCompliance.getEcodesignGrade(Math.trunc(reports.categories[lighthouseMetrics[element]].score * 100)) : formatCompliance.getAccessibilityGrade(Math.trunc(reports.categories[lighthouseMetrics[element]].score * 100))
formattedReports[element] = { score, complianceLevel }
} else {
score = Math.trunc(reports.audits[lighthouseMetrics[element]].score * 100)
displayValue = reports.audits[lighthouseMetrics[element]].displayValue
displayValue = displayValue ? Number(displayValue.replace(',', '').match(reg)[0]) : 0
complianceLevel = formatCompliance.getEcodesignGrade(Math.trunc(reports.audits[lighthouseMetrics[element]].score * 100))
formattedReports[element] = { score, displayValue, complianceLevel }
}
} catch (error) {
console.error(error)
}
Expand Down
4 changes: 4 additions & 0 deletions EcoSonar-API/services/greenit-analysis/analyseService.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,18 @@ export default async function analyse (urlList, projectName, username, password,
]

const proxyConfiguration = await authenticationService.useProxyIfNeeded(projectName)
console.log('Get proxy successful');
if (proxyConfiguration) {
browserArgs.push(proxyConfiguration)
}

const userJourneyEnabled = process.env.ECOSONAR_ENV_USER_JOURNEY_ENABLED || 'false'
console.log('Finished retrieving variable ECOSONAR_ENV_USER_JOURNEY_ENABLED');
if (userJourneyEnabled === 'true') {
console.log('Your EcoSonar project is using user journey to audit your website, GreenIT analysis will be made into different Chromium browser for right cookies configuration')
reports = await launchAllAnalysisOnDifferentBrowser(browserArgs, urlList, projectName, username, password, autoscroll)
} else {
console.log('launchAllAnalysisOnSameBrowser');
reports = await launchAllAnalysisOnSameBrowser(browserArgs, urlList, projectName, username, password, autoscroll)
}
return reports
Expand Down Expand Up @@ -83,6 +86,7 @@ async function launchAllAnalysisOnSameBrowser (browserArgs, urlList, projectName
} catch (error) {
console.error('\x1b[31m%s\x1b[0m', error)
} finally {
console.log('Closing browser for launchAllAnalysisOnSameBrowser');
await closeBrowser(browser)
}
return reports
Expand Down
40 changes: 29 additions & 11 deletions EcoSonar-API/services/lighthouse/lighthouse.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,19 @@ export default async function lighthouseAnalysis (urlList, projectName, username
'--disable-setuid-sandbox', // but security issues
'--ignore-certificate-errors',
'--window-size=1920,1080',
'--start-maximized'
'--start-maximized',
'--remote-debugging-port=36951'
]

const proxyConfiguration = await authenticationService.useProxyIfNeeded(projectName)
if (proxyConfiguration) {
browserArgs.push(proxyConfiguration)
}

// start browser
const browser = await puppeteer.launch({
const browserLight = await puppeteer.launch({
headless: 'new',
args: browserArgs,
timeout: 0,
ignoreHTTPSErrors: true,
// Keep gpu horsepower in headless
ignoreDefaultArgs: [
Expand All @@ -34,13 +35,22 @@ export default async function lighthouseAnalysis (urlList, projectName, username

const results = []

const generateReportForHome = async (url, index) => {
//Launch lighthouse analysis
const homePageReport = await lighthouse(url, config);
const homePageReportLhr = homePageReport.lhr;
results[index] = { ...homePageReportLhr, url }
console.log(`home page performance report generated successfully`);
};

try {
let lighthouseResults
let authenticatedPage
let userJourney
const loginSucceeded = await authenticationService.loginIfNeeded(browser, projectName, username, password)
const loginSucceeded = await authenticationService.loginIfNeeded(browserLight, projectName, username, password)
if (loginSucceeded) {
for (const [index, url] of urlList.entries()) {
const page = await browser.newPage() // prevent browser to close before ending all pages analysis
const page = await browserLight.newPage() // prevent browser to close before ending all pages analysis
try {
console.log('Lighthouse Analysis launched for url ' + url)
await userJourneyService.getUserFlow(projectName, url)
Expand All @@ -50,18 +60,25 @@ export default async function lighthouseAnalysis (urlList, projectName, username
console.log(error.message)
})
if (userJourney) {
lighthouseResults = await userJourneyService.playUserFlowLighthouse(url, browser, userJourney)
authenticatedPage = await userJourneyService.playUserFlowLighthouse(url, browserLight, userJourney)
} else {
// Wait for Lighthouse to open url, then inject our stylesheet.
browser.on('targetchanged', async target => {
browserLight.on('targetchanged', async target => {
if (page && page.url() === url) {
await page.addStyleTag({ content: '* {color: red}' })
}
})
}
//If the url requires an authentication
if (authenticatedPage) {
console.log('Light house analysis with authentication in progress for the url '+ authenticatedPage.url());
await generateReportForHome(authenticatedPage.url(), index);
} else {
lighthouseResults = await lighthouse(url, { disableStorageReset: true }, config, page)
console.log('Light house analysis without authentication in progress for the url '+ url);
results[index] = { ...lighthouseResults.lhr, url }
}
console.log('Lighthouse Analysis ended for url ' + url)
results[index] = { ...lighthouseResults.lhr, url }

} catch (error) {
console.error('LIGHTHOUSE ANALYSIS - An error occured when auditing ' + url)
console.error('\x1b[31m%s\x1b[0m', error)
Expand All @@ -73,7 +90,8 @@ export default async function lighthouseAnalysis (urlList, projectName, username
} catch (error) {
console.error('\x1b[31m%s\x1b[0m', error)
} finally {
await browser.close()
console.log('Closing browser for Lighthouse');
await browserLight.close();
}
return results
return results;
}
12 changes: 8 additions & 4 deletions EcoSonar-API/services/userJourneyService.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { startFlow } from 'lighthouse'
import lighthouse from 'lighthouse'
import { setTimeout } from "timers/promises";
import PuppeteerHar from '../utils/PuppeteerHar.js'
import { clickOnElement, waitForSelectors, applyChange } from '../utils/playSelectors.js'
import urlsProjectRepository from '../dataBase/urlsProjectRepository.js'
Expand Down Expand Up @@ -72,6 +74,8 @@ UserJourneyService.prototype.playUserJourney = async function (url, browser, use
UserJourneyService.prototype.playUserFlowLighthouse = async function (url, browser, userJourney) {
const timeout = 10000
const targetPage = await browser.newPage()
// go to url
await targetPage.goto(url, { timeout: 0, waitUntil: 'networkidle2' })
await targetPage.setViewport(viewPortParams)
const flow = await startFlow(targetPage, { name: url })
const steps = userJourney.steps
Expand Down Expand Up @@ -99,10 +103,10 @@ UserJourneyService.prototype.playUserFlowLighthouse = async function (url, brows
break
}
}
// await targetPage.waitForNavigation()
targetPage.close()
const lighthouseResults = await flow.createFlowResult()
return lighthouseResults.steps[0]
//Wait browser to render completely
await setTimeout(5000);

return targetPage;
}

UserJourneyService.prototype.insertUserFlow = async function (projectName, url, userFlow) {
Expand Down
2 changes: 1 addition & 1 deletion EcoSonar-API/swagger.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const swagger = {
swaggerDefinition: {
info: {
title: 'API EcoSonar',
version: '3.5',
version: '3.6',
description: 'Swagger UI of EcoSonar API'
}
},
Expand Down
10 changes: 6 additions & 4 deletions EcoSonar-API/utils/playSelectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@ async function waitForSelectors (selectors, frame, options) {
async function waitForSelector (selector, frame, options) {
let element = null
const firstSelector = selector[0]
if (selector.length === 1 && firstSelector.lastIndexOf('*') === firstSelector.length - 1 && firstSelector.indexOf('#') === 0) {
const idStartsWith = firstSelector.substring(1, firstSelector.length - 2)
return await frame.waitForSelector(`[id^="${idStartsWith}"]`)
}
if (selector.length === 1 && firstSelector.indexOf('#') === 0) {
const idStartsWith = firstSelector.replace('#', '')
const selectorPicker = `[id="${idStartsWith}"]`
console.log('Selector being picked '+ idStartsWith)
return await frame.waitForSelector(firstSelector)
}

for (let i = 0; i < selector.length; i++) {
const part = selector[i]
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion EcoSonar-SonarQube/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>com.ls</groupId>
<artifactId>ecosonar</artifactId>
<version>3.5</version>
<version>3.6</version>

<packaging>sonar-plugin</packaging>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export default class AnalysisPerUrlPanel extends React.PureComponent {
})
getAnalysisUrlConfiguration(this.state.projectName, this.state.selectedUrl)
.then((res) => {
if (res !== undefined && res.lastAnalysis.greenit !== null && res.lastAnalysis.lighthouse !== null && res.lastAnalysis.w3c !== null && res.deployments.greenit.length !== 0 && res.deployments.lighthouse.length !== 0 && res.deployments.lighthouse.w3c !== 0) {
if (res !== undefined) {
this.setState({
greenItLastAnalysis: res.lastAnalysis.greenit,
lighthouseLastAnalysis: res.lastAnalysis.lighthouse,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export default class EcoSonarAnalysisPage extends React.PureComponent {
initEcoSonarAnalysisPage (projectName) {
getAnalysisForProjectConfiguration(projectName)
.then((analysis) => {
if (analysis !== undefined && analysis.lastAnalysis.greenit !== null && analysis.lastAnalysis.lighthouse !== null && analysis.lastAnalysis.w3c !== null && analysis.deployments.greenit.length !== 0 && analysis.deployments.lighthouse.length !== 0 && analysis.deployments.lighthouse.w3c !== 0) {
if (analysis !== undefined && analysis.lastAnalysis.greenit !== null && analysis.deployments.greenit.length !== 0) {
const dateGreenitLastAnalysis = analysis.lastAnalysis.greenit !== null && analysis.lastAnalysis.greenit.dateAnalysis
? `${new Date(analysis.lastAnalysis.greenit.dateAnalysis).toDateString()} - ${new Date(analysis.lastAnalysis.greenit.dateAnalysis).toLocaleTimeString([], { hour12: false })} `
: null
Expand Down
Loading

0 comments on commit 0f9378d

Please sign in to comment.