Skip to content

Commit 2ce029f

Browse files
committed
PR feedback
- update console.logs to core.infos
1 parent 74f131f commit 2ce029f

7 files changed

Lines changed: 54 additions & 33 deletions

File tree

.github/actions/find/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ https://primer.style/octicons/
2525

2626
#### `scans`
2727

28-
**Optional** Stringified JSON array of scans (string) to perform. If not provided, only axe will be performed. Valid options currently include 'axe'
28+
**Optional** Stringified JSON array of scans (string) to perform. If not provided, only axe will be performed.
2929

3030
### Outputs
3131

.github/actions/find/src/findForUrl.ts

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ import AxeBuilder from '@axe-core/playwright'
33
import playwright from 'playwright'
44
import {AuthContext} from './AuthContext.js'
55
import {generateScreenshots} from './generateScreenshots.js'
6-
import {loadPlugins} from './pluginManager.js'
6+
import {loadPlugins, invokePlugin} from './pluginManager.js'
77
import {getScansContext} from './scansContextProvider.js'
88
import axe from 'axe-core'
9+
import core from '@actions/core'
910

1011
export async function findForUrl(
1112
url: string,
@@ -20,7 +21,7 @@ export async function findForUrl(
2021
const context = await browser.newContext(contextOptions)
2122
const page = await context.newPage()
2223
await page.goto(url)
23-
console.log(`Scanning ${page.url()}`)
24+
core.info(`Scanning ${page.url()}`)
2425

2526
const findings: Finding[] = []
2627
const addFinding = (findingData: Finding) => {
@@ -35,22 +36,14 @@ export async function findForUrl(
3536
rawFindings = await new AxeBuilder({page}).analyze()
3637
}
3738

38-
// - this if condition is not required, but makes it easier to make assertions
39-
// in unit tests on whether 'loadPlugins' was called or not (it does have the added
40-
// benefit of completely skipping plugin loading if we just want axe - so thats
41-
// a minor performance boost)
42-
// - alternatively, we can wrap the 'plugin.default(...)' call in another function
43-
// and make assertions on whether that function was called or not
44-
// - the other option is to wrap each plugin in a class instance
45-
// and make assertions on something like 'plugin.run' being called or not
4639
if (scansContext.shouldRunPlugins) {
4740
const plugins = await loadPlugins()
4841
for (const plugin of plugins) {
4942
if (scansContext.scansToPerform.includes(plugin.name)) {
50-
console.log('Running plugin: ', plugin.name)
51-
await plugin.default({page, addFinding, url})
43+
core.info(`Running plugin: ${plugin.name}`)
44+
await invokePlugin({plugin, page, addFinding, url})
5245
} else {
53-
console.log(`Skipping plugin ${plugin.name} because it is not included in the 'scans' input`)
46+
core.info(`Skipping plugin ${plugin.name} because it is not included in the 'scans' input`)
5447
}
5548
}
5649
}
@@ -73,7 +66,7 @@ export async function findForUrl(
7366
}))
7467
findings.push(...(axeFindings || []))
7568
} catch (e) {
76-
console.error('Error during accessibility scan:', e)
69+
core.error(`Error during accessibility scan: ${e}`)
7770
}
7871
await context.close()
7972
await browser.close()

.github/actions/find/src/generateScreenshots.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import fs from 'node:fs'
22
import path from 'node:path'
33
import crypto from 'node:crypto'
44
import type {Page} from 'playwright'
5+
import core from '@actions/core'
56

67
// Use GITHUB_WORKSPACE to ensure screenshots are saved in the workflow workspace root
78
// where the artifact upload step can find them
@@ -12,9 +13,9 @@ export const generateScreenshots = async function (page: Page) {
1213
// Ensure screenshot directory exists
1314
if (!fs.existsSync(SCREENSHOT_DIR)) {
1415
fs.mkdirSync(SCREENSHOT_DIR, {recursive: true})
15-
console.log(`Created screenshot directory: ${SCREENSHOT_DIR}`)
16+
core.info(`Created screenshot directory: ${SCREENSHOT_DIR}`)
1617
} else {
17-
console.log(`Using existing screenshot directory ${SCREENSHOT_DIR}`)
18+
core.info(`Using existing screenshot directory ${SCREENSHOT_DIR}`)
1819
}
1920

2021
try {
@@ -28,9 +29,9 @@ export const generateScreenshots = async function (page: Page) {
2829
const filepath = path.join(SCREENSHOT_DIR, filename)
2930

3031
fs.writeFileSync(filepath, screenshotBuffer)
31-
console.log(`Screenshot saved: ${filename}`)
32+
core.info(`Screenshot saved: ${filename}`)
3233
} catch (error) {
33-
console.error('Failed to capture/save screenshot:', error)
34+
core.error(`Failed to capture/save screenshot: ${error}`)
3435
screenshotId = undefined
3536
}
3637

.github/actions/find/src/pluginManager.ts

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {fileURLToPath} from 'url'
44
import {dynamicImport} from './dynamicImport.js'
55
import type {Finding} from './types.d.js'
66
import playwright from 'playwright'
7+
import core from '@actions/core'
78

89
// Helper to get __dirname equivalent in ES Modules
910
const __filename = fileURLToPath(import.meta.url)
@@ -18,7 +19,7 @@ const plugins: Plugin[] = []
1819
let pluginsLoaded = false
1920

2021
export async function loadPlugins() {
21-
console.log('loading plugins')
22+
core.info('loading plugins')
2223

2324
try {
2425
if (!pluginsLoaded) {
@@ -27,7 +28,7 @@ export async function loadPlugins() {
2728
}
2829
} catch {
2930
plugins.length = 0
30-
console.log(abortError)
31+
core.error(abortError)
3132
} finally {
3233
pluginsLoaded = true
3334
return plugins
@@ -47,7 +48,7 @@ export function clearCache() {
4748

4849
// exported for mocking/testing. not for actual use
4950
export async function loadBuiltInPlugins() {
50-
console.log('Loading built-in plugins')
51+
core.info('Loading built-in plugins')
5152

5253
const pluginsPath = '../../../scanner-plugins/'
5354
await loadPluginsFromPath({
@@ -58,7 +59,7 @@ export async function loadBuiltInPlugins() {
5859

5960
// exported for mocking/testing. not for actual use
6061
export async function loadCustomPlugins() {
61-
console.log('Loading custom plugins')
62+
core.info('Loading custom plugins')
6263

6364
const pluginsPath = process.cwd() + '/.github/scanner-plugins/'
6465
await loadPluginsFromPath({
@@ -74,15 +75,26 @@ export async function loadPluginsFromPath({readPath, importPath}: {readPath: str
7475
for (const pluginFolder of res) {
7576
const pluginFolderPath = path.join(importPath, pluginFolder)
7677
if (fs.lstatSync(pluginFolderPath).isDirectory()) {
77-
console.log('Found plugin: ', pluginFolder)
78+
core.info(`Found plugin: ${pluginFolder}`)
7879
plugins.push(await dynamicImport(path.join(importPath, pluginFolder, '/index.js')))
7980
}
8081
}
8182
} catch (e) {
8283
// - log errors here for granular info
83-
console.log('error: ')
84-
console.log(e)
84+
core.error('error: ')
85+
core.error(e as Error)
8586
// - throw error to handle aborting the plugin scans
8687
throw e
8788
}
8889
}
90+
91+
92+
type InvokePluginParams = {
93+
plugin: Plugin,
94+
page: playwright.Page,
95+
addFinding: (findingData: Finding) => void,
96+
url: string
97+
}
98+
export function invokePlugin({ plugin, page, addFinding, url }: InvokePluginParams) {
99+
return plugin.default({page, addFinding, url})
100+
}

.github/actions/find/src/scansContextProvider.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ let scansContext: ScansContext | undefined
99

1010
export function getScansContext() {
1111
if (!scansContext) {
12-
const scansJson = core.getInput('scans', {required: false})
13-
const scansToPerform = JSON.parse(scansJson || '[]')
12+
const scansInput = core.getInput('scans', {required: false})
13+
const scansToPerform = JSON.parse(scansInput || '[]')
1414
// - if we don't have a scans input
1515
// or we do have a scans input, but it only has 1 item and its 'axe'
1616
// then we only want to run 'axe' and not the plugins
@@ -23,7 +23,7 @@ export function getScansContext() {
2323
// (only axe scan) for backwards compatability.
2424
// - we can enforce using the 'scans' input in a future major release and
2525
// mark it as required
26-
shouldPerformAxeScan: !scansJson || scansToPerform.includes('axe'),
26+
shouldPerformAxeScan: !scansInput || scansToPerform.includes('axe'),
2727
shouldRunPlugins: scansToPerform.length > 0 && !onlyAxeScan,
2828
}
2929
}

.github/actions/find/tests/findForUrl.test.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,15 @@ function clearAll() {
4242
describe('findForUrl', () => {
4343
vi.spyOn(core, 'getInput').mockImplementation(() => actionInput)
4444
vi.spyOn(pluginManager, 'loadPlugins').mockImplementation(() => Promise.resolve(loadedPlugins))
45+
vi.spyOn(pluginManager, 'invokePlugin')
4546

4647
async function axeOnlyTest() {
4748
clearAll()
4849

4950
await findForUrl('test.com')
5051
expect(AxeBuilder.prototype.analyze).toHaveBeenCalledTimes(1)
5152
expect(pluginManager.loadPlugins).toHaveBeenCalledTimes(0)
53+
expect(pluginManager.invokePlugin).toHaveBeenCalledTimes(0)
5254
}
5355

5456
describe('when no scans list is provided', () => {
@@ -68,23 +70,35 @@ describe('findForUrl', () => {
6870

6971
describe('and the list includes axe and other scans', () => {
7072
it('runs axe and plugins', async () => {
71-
actionInput = JSON.stringify(['axe', 'custom-scan'])
73+
loadedPlugins = [
74+
{name: 'custom-scan-1', default: vi.fn()},
75+
{name: 'custom-scan-2', default: vi.fn()},
76+
]
77+
78+
actionInput = JSON.stringify(['axe', 'custom-scan-1'])
7279
clearAll()
7380

7481
await findForUrl('test.com')
7582
expect(AxeBuilder.prototype.analyze).toHaveBeenCalledTimes(1)
7683
expect(pluginManager.loadPlugins).toHaveBeenCalledTimes(1)
84+
expect(pluginManager.invokePlugin).toHaveBeenCalledTimes(1)
7785
})
7886
})
7987

8088
describe('and the list does not include axe', () => {
8189
it('only runs plugins', async () => {
82-
actionInput = JSON.stringify(['custom-scan'])
90+
loadedPlugins = [
91+
{name: 'custom-scan-1', default: vi.fn()},
92+
{name: 'custom-scan-2', default: vi.fn()},
93+
]
94+
95+
actionInput = JSON.stringify(['custom-scan-1', 'custom-scan-2'])
8396
clearAll()
8497

8598
await findForUrl('test.com')
8699
expect(AxeBuilder.prototype.analyze).toHaveBeenCalledTimes(0)
87100
expect(pluginManager.loadPlugins).toHaveBeenCalledTimes(1)
101+
expect(pluginManager.invokePlugin).toHaveBeenCalledTimes(2)
88102
})
89103
})
90104

.github/actions/find/tests/pluginManager.test.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {describe, it, expect, vi, beforeEach} from 'vitest'
33
import * as fs from 'fs'
44
import * as dynamicImportModule from '../src/dynamicImport.js'
55
import * as pluginManager from '../src/pluginManager.js'
6+
import core from '@actions/core'
67

78
// - enable spying on fs
89
// https://vitest.dev/guide/browser/#limitations
@@ -52,10 +53,10 @@ describe('loadPlugins', () => {
5253

5354
it('Aborts loading all plugins', async () => {
5455
pluginManager.clearCache()
55-
const consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {})
56+
const logSpy = vi.spyOn(core, 'error').mockImplementation(() => {})
5657
const plugins = await pluginManager.loadPlugins()
5758
expect(plugins.length).toBe(0)
58-
expect(consoleLogSpy).toHaveBeenCalledWith(pluginManager.abortError)
59+
expect(logSpy).toHaveBeenCalledWith(pluginManager.abortError)
5960
})
6061
})
6162
})

0 commit comments

Comments
 (0)