Skip to content

Commit 4069268

Browse files
committed
Merge branch 'development' of https://github.com/EmptyWork/lighthouse-accessibility-thesis into development
2 parents f00374b + ff20724 commit 4069268

12 files changed

+311
-7
lines changed

.babelrc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"env": {
3+
"test": {
4+
"plugins": ["@babel/plugin-transform-modules-commonjs"]
5+
}
6+
}
7+
}

index.class.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { existsSync, copyFileSync } from 'fs'
2+
import ThesisLighthouse from './src/lib/application.class.js'
3+
if (!existsSync('./src/urlList.class.js')) copyFileSync('./src/urlList.class.example', './src/urlList.class.js')
4+
import Config from "./src/urlList.class.js"
5+
6+
const app = new ThesisLighthouse(Config)

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
{
22
"name": "lighthouse-link-thesis",
3-
"version": "0.0.4",
3+
"version": "0.0.5c",
44
"description": "a way to automatically use lighthouse to get accessibility report number",
5-
"main": "index.js",
5+
"main": "index.class.js",
66
"type": "module",
77
"scripts": {
8-
"start": "npm run clean && npm run test",
9-
"test": "node index.js",
10-
"clean": "node clean.js"
8+
"start": "npm run clean && npm run build",
9+
"start:class": "npm run clean && npm run build:class",
10+
"build": "node index",
11+
"build:class": "node index.class",
12+
"test": "jest",
13+
"test:debug": "jest --detectOpenHandles",
14+
"clean": "node clean"
1115
},
1216
"keywords": [
1317
"automated-tools",
@@ -18,5 +22,9 @@
1822
"dependencies": {
1923
"async": "^3.2.4",
2024
"lighthouse": "^10.2.0"
25+
},
26+
"devDependencies": {
27+
"@babel/plugin-transform-modules-commonjs": "^7.22.5",
28+
"jest": "^29.6.2"
2129
}
2230
}

src/lib/application.class.js

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { series } from "async"
2+
import { exec } from 'child_process'
3+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs'
4+
import { getCategoriesFlags, getCategoriesFromCategoriesFlags, getCurrentCategories } from "./categoriesHandlers.class.js"
5+
import Command from "./commandHandlers.class.js"
6+
7+
export default class ThesisLighthouse {
8+
options
9+
execOptions
10+
urlList
11+
constructor({ urlList, appOptions, execOptions }) {
12+
this.options = appOptions
13+
this.execOptions = execOptions
14+
this.urlList = urlList
15+
}
16+
17+
testURL(urlToCheck, options = {}) {
18+
const { commandToRun } = Command.make(urlToCheck, options)
19+
if (options?.consoleLog ?? true) console.log(`Running Test on ${urlToCheck}`)
20+
21+
series([
22+
() => exec(commandToRun, this.execOptions, this.execResult.bind(this))
23+
])
24+
}
25+
26+
execResult(err = null, out, outerr = null) {
27+
const currentTime = new Date().toLocaleTimeString().replaceAll(":", "_")
28+
let accessibilityScores = (!existsSync('./out/scores.json')) ? readFileSync('./src/scores.json') : readFileSync('./out/scores.json')
29+
30+
const data = JSON.parse(out)
31+
32+
// const { commandToRun } = makeCommandFromURL(data?.requestedUrl, this.options)
33+
if (this.options?.consoleLog) console.log(`Stopped Test on ${data?.requestedUrl}`)
34+
35+
const accessibilityScoresJSON = JSON.parse(accessibilityScores)
36+
const categoriesScoresObject = {}
37+
const categories = getCategoriesFromCategoriesFlags(this.options?.categories)
38+
const optionCategories = getCurrentCategories(categories)
39+
40+
optionCategories.forEach(category => {
41+
let categoryScore = data?.categories[category].score
42+
43+
categoriesScoresObject[category] = categoryScore
44+
})
45+
46+
accessibilityScoresJSON[data?.requestedUrl] = categoriesScoresObject
47+
48+
const newAccessibilityJSON = JSON.stringify(accessibilityScoresJSON)
49+
50+
if (!existsSync('./out/')) mkdirSync('./out/')
51+
52+
if (!existsSync('./out/logs')) mkdirSync('./out/logs')
53+
54+
const REGEX_HTTPS_HTTP = /^(http|https):\/\/(www.|)/g
55+
56+
const logFileNameBasedOnUrl = data?.requestedUrl.replace(REGEX_HTTPS_HTTP, '').replaceAll("/", "").split('.').reverse().join('.')
57+
const rawOutputFilename = `./out/logs/${logFileNameBasedOnUrl}-${optionCategories
58+
.join('-')}-${currentTime}.json`
59+
60+
writeFileSync(rawOutputFilename, JSON.stringify(data), { flag: 'w' })
61+
return writeFileSync('./out/scores.json', newAccessibilityJSON, { flag: 'w' })
62+
}
63+
64+
start() {
65+
if (this.options?.consoleLog) console.log(this.options)
66+
67+
const isOptionsCategories = getCategoriesFlags(this.options?.categories)
68+
const currentFlags = `${isOptionsCategories}\n\t--output json \n\t--disable-full-page-screenshot \n\t--chrome-flags="\n\t\t--no-sandbox \n\t\t--headless \n\t\t--disable-gpu"`
69+
70+
console.log(`ThesisLighthouse ${process.env.npm_package_version} - Thesis Example Code`)
71+
console.log(`Running with these flags: ${currentFlags}\n`)
72+
73+
this.urlList.forEach((url, index) => { this.testURL(url, this.options) })
74+
}
75+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import Utility from './utilities.class.js'
2+
3+
class Categories {
4+
// getCategoriesFlags = array => {
5+
getFlags = array => {
6+
return (!Utility.isEmpty(array) ?? false) ? `--only-categories=${lighthouseCategories(array ?? "accessibility")} ` : ""
7+
}
8+
9+
// getCurrentCategories = categories => {
10+
getCurrent = categories => {
11+
return categories ?? ["accessibility", "pwa", "best-practices", "performance", "seo"]
12+
}
13+
14+
// lighthouseCategories = (categories = []) => {
15+
lighthouse = (categories = []) => {
16+
return (typeof categories == "string") ? categories : categories.join(',')
17+
}
18+
19+
// getCategoriesFromCategoriesFlags = array => {
20+
getFromFlags = array => {
21+
return (!Utility.isEmpty(array)) ? array : undefined
22+
}
23+
}
24+
25+
export const {
26+
getFlags: getCategoriesFlags, // deprecated: only use this for non-class implementation
27+
lighthouse: lighthouseCategories, // deprecated: only use this for non-class implementation
28+
getCurrent: getCurrentCategories, // deprecated: only use this for non-class implementation
29+
getFromFlags: getCategoriesFromCategoriesFlags // deprecated: only use this for non-class implementation
30+
} = new Categories()
31+
export default new Categories()

src/lib/commandHandlers.class.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { getCategoriesFlags } from "./categoriesHandlers.class.js"
2+
3+
class Command {
4+
make = (url, options) => {
5+
const isOptionsCategories = getCategoriesFlags(options?.categories)
6+
const currentFlags = `${isOptionsCategories}--output json --disable-full-page-screenshot --chrome-flags="--no-sandbox --headless --disable-gpu"`
7+
const commandToRun = `lighthouse ${url} ${currentFlags}`
8+
return { commandToRun, currentFlags }
9+
}
10+
}
11+
12+
export const {
13+
make: makeCommandFromURL // deprecated: only use this for non-class implementation
14+
} = new Command()
15+
export default new Command()

src/lib/utilities.class.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
class Utility {
2+
isEmpty = data => {
3+
let result;
4+
if (typeof data === 'array') result = this.#isArrayEmpty(data)
5+
if (typeof data === 'object') result = this.#isObjEmpty(data)
6+
7+
return result
8+
}
9+
10+
#isArrayEmpty = (data = []) => {
11+
return (data === undefined || data.length === 0) ? false : true
12+
}
13+
14+
#isObjEmpty = (data = {}) => {
15+
for (const prop in data)
16+
if (Object.hasOwn(data, prop)) return false
17+
return true
18+
}
19+
}
20+
21+
export default new Utility()

src/urlList.class.example

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
export default class Config {
2+
static urlList = [
3+
// you can add more links in here, but keep in mind, the more links you add
4+
// the more resource it will use
5+
"https://emptywork.my.id", // my main website
6+
]
7+
8+
static appOptions = {
9+
"categories": ["accessibility", "seo"],
10+
"consoleLog": true
11+
}
12+
13+
static execOptions = {
14+
"maxBuffer": 2048 * 1024
15+
}
16+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import Categories from "../../src/lib/categoriesHandlers.class.js"
2+
3+
const firstTestCategories = ["accessibility"]
4+
const secondTestCategories = ["accessibility", "seo", "pwa"]
5+
6+
test('getCategories from an Array', () => {
7+
expect(
8+
Categories.getFlags(firstTestCategories)
9+
).toStrictEqual("--only-categories=accessibility ");
10+
});
11+
12+
test('getCategories from an Array with more than one item', () => {
13+
expect(
14+
Categories.getFlags(secondTestCategories)
15+
).toStrictEqual("--only-categories=accessibility,seo,pwa ");
16+
});
17+
18+
test('getCurrent from Array', () => {
19+
expect(
20+
Categories.getCurrent(firstTestCategories)
21+
).toStrictEqual(["accessibility"])
22+
});
23+
24+
test('getCurrent from Array with more than one item', () => {
25+
expect(
26+
Categories.getCurrent(secondTestCategories)
27+
).toStrictEqual(["accessibility", "seo", "pwa"])
28+
});
29+
30+
test('lighthouse from Array', () => {
31+
expect(
32+
Categories.lighthouse(firstTestCategories)
33+
).toStrictEqual("accessibility")
34+
})
35+
36+
test('lighthouse from Array with more than one item', () => {
37+
expect(
38+
Categories.lighthouse(secondTestCategories)
39+
).toStrictEqual("accessibility,seo,pwa")
40+
})
41+
42+
test('getFromFlags from Array', () => {
43+
expect(
44+
Categories.getFromFlags(firstTestCategories)
45+
).toStrictEqual(["accessibility"])
46+
})
47+
48+
test('getFromFlags from empty Array', () => {
49+
expect(
50+
Categories.getFromFlags([])
51+
).toBe(undefined)
52+
})

0 commit comments

Comments
 (0)