Skip to content

Commit b39dcc1

Browse files
Olayinka AdelakunOlayinka Adelakun
authored andcommitted
Merge remote-tracking branch 'origin/release-1.11.0' into LE-1653
2 parents 49d091e + d2d1bdc commit b39dcc1

988 files changed

Lines changed: 74538 additions & 116999 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
---
2+
name: ibm-a11y-automation
3+
description: Run Langflow's local accessibility scanner script against frontend routes from src/frontend/src/routes.tsx and summarize the JSON report.
4+
---
5+
6+
# Langflow Accessibility Scanner
7+
8+
Use this skill when asked to scan Langflow frontend pages for accessibility issues.
9+
10+
## Scanner
11+
12+
Use the Python script:
13+
14+
```bash
15+
uv run python scripts/a11y/a11y_scan.py \
16+
--url http://localhost:3000 \
17+
--routes-file scripts/a11y/a11y_routes.json \
18+
--route-group static \
19+
--out /tmp/langflow-a11y-report.json \
20+
--markdown /tmp/langflow-a11y-report.md \
21+
--html /tmp/langflow-a11y-report.html \
22+
--timeout-ms 45000
23+
```
24+
25+
Script options:
26+
27+
- `--url`: base app URL, usually `http://localhost:3000`.
28+
- `--routes-file`: route manifest JSON file. Prefer `scripts/a11y/a11y_routes.json`.
29+
- `--route-group`: manifest group to scan. Default: `static`.
30+
- `--routes`: comma-separated route paths to scan.
31+
- `--route`: one route path; can be repeated instead of `--routes`.
32+
- `--levels`: comma-separated issue levels. Default: `violation`.
33+
- `--out`: JSON report path.
34+
- `--markdown`: optional Markdown report path.
35+
- `--html`: optional self-contained HTML report path.
36+
- `--timeout-ms`: per-route timeout.
37+
- `--quiet-ms`: network quiet window before scanning. Default: `1000`.
38+
- `--states-file`: JSON file with explicit modal/state actions.
39+
- `--headed`: show browser while scanning.
40+
41+
## Route Selection
42+
43+
Use `scripts/a11y/a11y_routes.json` as the source of truth for route selection.
44+
45+
The normal CI/local batch is the manifest `static` group. Prefer that unless the user asks for custom, dynamic, or gated routes.
46+
47+
Common manifest-backed command:
48+
49+
```bash
50+
uv run python scripts/a11y/a11y_scan.py \
51+
--url http://localhost:3000 \
52+
--routes-file scripts/a11y/a11y_routes.json \
53+
--route-group static \
54+
--out /tmp/langflow-a11y-static.json \
55+
--markdown /tmp/langflow-a11y-static.md \
56+
--html /tmp/langflow-a11y-static.html
57+
```
58+
59+
Dynamic routes need real IDs before scanning:
60+
61+
- `/flow/:id/`
62+
- `/flow/:id/view`
63+
- `/playground/:id/`
64+
- `/assets/knowledge-bases/:sourceId/chunks`
65+
66+
For dynamic routes, get IDs from the loaded app, API responses, or existing test data before replacing placeholders.
67+
68+
## Examples
69+
70+
Scan one route:
71+
72+
```bash
73+
uv run python scripts/a11y/a11y_scan.py \
74+
--url http://localhost:3000 \
75+
--route /flows \
76+
--out /tmp/langflow-a11y-flows.json
77+
```
78+
79+
Scan multiple routes:
80+
81+
```bash
82+
uv run python scripts/a11y/a11y_scan.py \
83+
--url http://localhost:3000 \
84+
--routes-file scripts/a11y/a11y_routes.json \
85+
--route-group static \
86+
--out /tmp/langflow-a11y-report.json \
87+
--markdown /tmp/langflow-a11y-report.md \
88+
--html /tmp/langflow-a11y-report.html
89+
```
90+
91+
Scan more than violations:
92+
93+
```bash
94+
uv run python scripts/a11y/a11y_scan.py \
95+
--url http://localhost:3000 \
96+
--routes-file scripts/a11y/a11y_routes.json \
97+
--route-group static \
98+
--levels violation,potentialviolation,recommendation \
99+
--out /tmp/langflow-a11y-expanded.json
100+
```
101+
102+
Scan route plus modal states:
103+
104+
```bash
105+
uv run python scripts/a11y/a11y_scan.py \
106+
--url http://localhost:3000 \
107+
--states-file /tmp/langflow-a11y-states.json \
108+
--out /tmp/langflow-a11y-modal-report.json \
109+
--markdown /tmp/langflow-a11y-modal-report.md \
110+
--html /tmp/langflow-a11y-modal-report.html \
111+
--timeout-ms 45000
112+
```
113+
114+
State file shape:
115+
116+
```json
117+
[
118+
{
119+
"route": "/settings/global-variables",
120+
"states": [
121+
{
122+
"name": "new-global-variable-modal",
123+
"open": [
124+
{ "click": "[data-testid='api-key-button-store']" },
125+
{ "waitFor": "[role='dialog']" }
126+
],
127+
"close": [
128+
{ "press": "Escape" },
129+
{ "waitForHidden": "[role='dialog']" }
130+
]
131+
}
132+
]
133+
}
134+
]
135+
```
136+
137+
Supported state actions:
138+
139+
- `{ "click": "<css selector>" }`
140+
- `{ "clickText": "<visible text>" }`
141+
- `{ "clickRole": { "role": "button", "name": "Create" } }`
142+
- `{ "fill": { "selector": "<css selector>", "value": "text" } }`
143+
- `{ "press": "Escape" }`
144+
- `{ "press": { "selector": "<css selector>", "key": "Enter" } }`
145+
- `{ "waitFor": "<css selector>" }`
146+
- `{ "waitForHidden": "<css selector>" }`
147+
- `{ "waitForText": "<visible text>" }`
148+
- `{ "wait": 500 }`
149+
150+
## Report
151+
152+
The scanner always writes JSON. It can also write Markdown and HTML for presentation.
153+
154+
Use JSON for exact data. Use Markdown for PR comments or issues. Use HTML when the user wants a browsable report.
155+
156+
Summarize:
157+
158+
- report path
159+
- Markdown/HTML report paths, when generated
160+
- total issue count
161+
- per-route issue count
162+
- per-route API request count
163+
- per-route request failure count
164+
- top rule IDs
165+
166+
Use report fields directly:
167+
168+
- `totalIssues`
169+
- `results[].route`
170+
- `results[].state`
171+
- `results[].phase`
172+
- `results[].apiRequests`
173+
- `results[].requestFailures`
174+
- `results[].diagnostics`
175+
- `results[].issues[].ruleId`
176+
177+
## Rules
178+
179+
- Use only scanner output for findings.
180+
- Do not invent route names. Read `routes.tsx`.
181+
- Do not auto-click arbitrary buttons to find modals. Use explicit state actions.
182+
- Avoid destructive modal actions unless the user explicitly asks and data is safe.
183+
- If a route has zero API requests, mention that scan quality may be limited.
184+
- Ask before fixing files unless the user explicitly asks for fixes.

.github/workflows/a11y-scan.yml

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
1-
name: A11y / Playwright Scans
1+
name: A11y / IBM Equal Access Scans
22

33
on:
4-
# TEMP: remove before merging — allows testing the workflow from this
5-
# branch, since workflow_dispatch only registers once the file is on main.
6-
push:
7-
branches: [feat/a11y]
8-
# TEMP: remove before merging — run on PRs while validating the workflow.
94
pull_request:
105
schedule:
116
# Run nightly at 02:00 UTC, after the nightly build window
@@ -28,11 +23,11 @@ env:
2823
# Define the directory where Playwright browsers will be installed.
2924
# This path is used for caching across workflows
3025
PLAYWRIGHT_BROWSERS_PATH: "ms-playwright"
31-
PLAYWRIGHT_VERSION: "1.59.1"
26+
PLAYWRIGHT_VERSION: "1.60.0"
3227

3328
jobs:
3429
a11y-scan:
35-
name: IBM Equal Access
30+
name: Playwright scan runner
3631
runs-on: ubuntu-latest
3732
permissions:
3833
contents: read
@@ -118,7 +113,7 @@ jobs:
118113
- name: Install Python Dependencies
119114
run: uv sync
120115

121-
- name: Run Playwright Specs With IBM Scans
116+
- name: Run IBM Equal Access Scans
122117
shell: bash
123118
env:
124119
RUN_A11Y: "true"
@@ -134,17 +129,19 @@ jobs:
134129
test -n "$SCAN_SPECS"
135130
npx playwright test $SCAN_SPECS --project=chromium --workers=1 --retries=2
136131
137-
- name: Build Aggregated A11y Summary
132+
- name: Build IBM Scan Summary
138133
if: always()
139134
shell: bash
140135
run: |
141136
cd src/frontend
142137
if ls coverage/accessibility-reports/*.json > /dev/null 2>&1; then
143-
npm run a11y:report --silent
138+
npm run a11y:html-report --silent
144139
{
145-
echo '```text'
146-
npm run a11y:report --silent
147-
echo '```'
140+
echo '## Accessibility Report'
141+
echo ''
142+
echo 'Full route-by-route HTML report: download the `ibm-a11y-reports-${{ github.run_attempt }}` artifact from this run and open `index.html`.'
143+
echo ''
144+
npm run a11y:job-summary --silent
148145
} >> "$GITHUB_STEP_SUMMARY"
149146
else
150147
echo "No accessibility reports were generated." | tee -a "$GITHUB_STEP_SUMMARY"
@@ -154,7 +151,7 @@ jobs:
154151
if: always()
155152
uses: actions/upload-artifact@v6
156153
with:
157-
name: accessibility-reports-${{ github.run_attempt }}
154+
name: ibm-a11y-reports-${{ github.run_attempt }}
158155
path: src/frontend/coverage/accessibility-reports
159156
retention-days: 30
160157
overwrite: true

.github/workflows/a11y-unit-tests.yml

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: A11y / Unit Tests
1+
name: A11y / Component Unit Tests
22

33
on:
44
pull_request:
@@ -24,11 +24,10 @@ env:
2424

2525
jobs:
2626
a11y-unit-tests:
27-
name: Frontend jest-axe
27+
name: jest-axe
2828
runs-on: ubuntu-latest
2929
permissions:
3030
contents: read
31-
checks: write
3231
steps:
3332
- name: Checkout Repository
3433
uses: actions/checkout@v6
@@ -45,14 +44,5 @@ jobs:
4544
# These are regression locks: every a11y unit test passes as of the
4645
# component fixes in feat/a11y-unit-tests, so a failure here means a
4746
# real a11y regression and blocks the PR.
48-
- name: Run Frontend A11y Unit Tests
49-
run: make test_frontend_a11y_ci
50-
51-
- name: Publish A11y Test Results
52-
uses: mikepenz/action-junit-report@v5
53-
if: always()
54-
with:
55-
report_paths: "src/frontend/test-results/junit.xml"
56-
check_name: "A11y / Unit Test Results"
57-
fail_on_failure: true
58-
require_tests: true
47+
- name: Run jest-axe unit tests
48+
run: make test_frontend_a11y_unit_ci

0 commit comments

Comments
 (0)