🚀 Detect Broken & Non-Actionable Links in Angular ERP Systems Building a Cypress.io Automation Project
🧩 “In the world of enterprise software, reliability isn’t a feature — it’s the foundation.”
In this guide, we’ll automate the detection of broken and non-actionable links/buttons across every page of an Angular-based ERP using Cypress.io.
🧭 Why This Matters
ERP systems are the backbone of large-scale operations. From inventory to HR, every module relies on web links and UI buttons to function correctly. A single broken link or a non-responsive button can:
- ❌ Disrupt user flows
- ❌ Delay operations
- ❌ Undermine user trust
Yet with dozens or even hundreds of pages, manual link validation is impractical.
Automation is the key.
🎯 Goal of This Project
We’ll create a Cypress.io automation framework that:
- ✅ Logs in using secure credentials
- ✅ Iterates over a list of ERP URLs from a
.txtfile - ✅ Detects:
- 🔗 Broken
<a>links (e.g. 404, 500) - 🔘 Non-actionable buttons (e.g. disabled, missing handlers)
- ✅ Saves all findings in a clean
CSVreport:
page_url, broken_link, related_component🛠️ Tech Stack
- ✅ Cypress.io — End-to-end testing framework
- ✅ Node.js (v18+)
- ✅ PapaParse — CSV generation
- ✅
fs-extra– File read/write support
📁 Project Structure
erp-link-checker/
├── cypress/
│ ├── fixtures/
│ │ ├── erpPages.txt # List of ERP URLs to test
│ │ └── loginData.json # Login credentials
│ ├── support/
│ │ └── commands.js # Custom commands (optional)
│ └── e2e/
│ └── broken_links.cy.js # Main test logic
├── broken_links_report.csv # Output report
├── cypress.config.js
├── package.json🧪 Step-by-Step Implementation
1️⃣ Install Required Dependencies
npm init -y
npm install cypress papaparse fs-extra2️⃣ Prepare loginData.json
{
"login_url": "https://erp.example.com/login",
"email": "admin@company.com",
"password": "SecurePass@2025"
}3️⃣ Prepare erpPages.txt
Each line represents a page to test:
https://erp.example.com/dashboard
https://erp.example.com/sales
https://erp.example.com/purchase
...4️⃣ Cypress Test: broken_links.cy.js
import fs from 'fs-extra';
import Papa from 'papaparse';
const credentials = require('../fixtures/loginData.json');
const urls = fs.readFileSync('cypress/fixtures/erpPages.txt', 'utf8').split('\n').filter(Boolean);
const outputData = [];
function logIssue(page_url, broken_link, related_component) {
outputData.push({ page_url, broken_link, related_component });
}
describe('ERP System - Broken and Non-Actionable Link Checker', () => {
before(() => {
cy.visit(credentials.login_url);
cy.get('input[type=email]').type(credentials.email);
cy.get('input[type=password]').type(credentials.password);
cy.get('button[type=submit]').click();
cy.url().should('not.include', '/login');
});
urls.forEach((pageUrl) => {
it(`Scans: ${pageUrl}`, () => {
cy.visit(pageUrl);
// 🔗 Check <a> tags
cy.get('a[href]').each(($a) => {
const href = $a.prop('href');
if (href && !href.startsWith('javascript:')) {
cy.request({
url: href,
failOnStatusCode: false
}).then((resp) => {
if (resp.status >= 400) {
logIssue(pageUrl, href, $a.text().trim() || '<a> without label');
}
});
}
});
// 🔘 Check buttons
cy.get('button').each(($btn) => {
const isDisabled = $btn.prop('disabled') || $btn.attr('aria-disabled') === 'true';
const onclick = $btn.attr('onclick');
if (isDisabled || (!onclick && !$btn.attr('routerlink'))) {
logIssue(pageUrl, '[button]', $btn.text().trim() || '<button> without label');
}
});
});
});
after(() => {
const csv = Papa.unparse(outputData);
fs.writeFileSync('broken_links_report.csv', csv);
});
});5️⃣ Run It!
npx cypress run --e2eAfter the run, check your generated broken_links_report.csv:
page_url,broken_link,related_component
https://erp.example.com/dashboard,https://erp.example.com/broken-link,Sales Button
...✅ Best Practices
TipDescription🔐 Use env varsNever hard-code passwords in your test files🧩 Use data-testidAsk devs to add identifiers to buttons/links🔁 Run on CI/CDAutomate these checks weekly or per build📦 Group reportsSave historical CSVs with timestamps
💡 Why Cypress Over Other Tools?
- 📸 Screenshot/Video support on failures
- 🧪 Powerful selector engine
- 🔄 Full control of browser lifecycle
- ⚡ Fast and JavaScript-native
🚀 Final Thoughts
Broken links and non-actionable UI components can silently erode the reliability of even the best-designed ERP systems.
By automating these checks with Cypress.io, you:
- Prevent user frustration
- Improve QA confidence
- Keep your ERP healthy at scale
💬 What’s Next?
- Add email notifications when issues are detected
- Expand detection to modals, dropdowns, or dynamic components
- Export to PDF reports with charts via Cypress Dashboard
Want the full source code as a GitHub template? Drop a comment or DM and I’ll send it over.
If you found this guide helpful, give it a 💖 or 📝 bookmark — and share with your QA or DevOps team!
Get Mohamed Said Ibrahim’s stories in your inbox
Join Medium for free to get updates from this writer.
#CypressIO #QA #AutomationTesting #Angular #ERP #BrokenLinks #EndToEndTesting #JavaScript #MediumEngineering










