📦 EqualifyEverything / equalify-schema

📄 axe-core.js · 119 lines
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119function convertAxeResultsToStream(axeResults) {
    let tagIdCounter = 1;
    let nodeIdCounter = 1;
    let ruleTagId, messageTagId;

    const nodeMap = new Map();
    const messageMap = new Map();
    const tagMap = new Map(); 

    const streamData = {
        urls: [{ urlId: 1, url: axeResults.results.url }], // This script only converts one url
        messages: [],
        tags: [],
        nodes: []
    };

    const ensureTags = () => {
        if (!ruleTagId) {
            const ruleTag = 'axe-core Rule';
            ruleTagId = getOrCreateTagId(ruleTag);
        }
        if (!messageTagId) {
            const messageTag = 'axe-core Message';
            messageTagId = getOrCreateTagId(messageTag); 
        }
    };

    const formatRuleId = (id) => id.replace(/-/g, ' ').split(' ').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');

    const getOrCreateTagId = (tag) => {
        if (tagMap.has(tag)) {
            return tagMap.get(tag);
        } else {
            const tagId = tagIdCounter++;
            tagMap.set(tag, tagId);
            streamData.tags.push({ tagId, tag });
            return tagId;
        }
    };

    const getOrCreateNodeId = (html, targets) => {
        const key = `${html}::${targets.join(',')}`;
        if (!nodeMap.has(key)) {
            const nodeId = nodeIdCounter++;
            nodeMap.set(key, nodeId);
            streamData.nodes.push({ 
                nodeId, 
                html, 
                targets, 
                relatedUrlIds: [1],
                equalified: false  
             });
        }
        return nodeMap.get(key);
    };

    const addOrUpdateMessage = (messageText, messageType, isRule, html, targets, additionalTags = []) => {
        const nodeId = getOrCreateNodeId(html, targets);
        const key = `${messageText}::${messageType}`;
        const tagIds = [isRule ? ruleTagId : messageTagId].concat(
            additionalTags.map(tag => getOrCreateTagId(tag))
        );

        if (!messageMap.has(key)) {
            const message = {
                message: messageText,
                relatedTagIds: tagIds,
                relatedNodeIds: [nodeId],
                type: messageType
            };
            streamData.messages.push(message);
            messageMap.set(key, message);
        } else {
            const existingMessage = messageMap.get(key);
            if (!existingMessage.relatedNodeIds.includes(nodeId)) {
                existingMessage.relatedNodeIds.push(nodeId);
            }
        }
    };

    const processIssues = (issues, messageType) => {
        ensureTags();

        issues.forEach(issue => {
            const formattedRuleId = formatRuleId(issue.id);
            const ruleMessageText = `${formattedRuleId} Rule: ${issue.description}. ${issue.help}. More information: ${issue.helpUrl}`;

            issue.nodes.forEach(node => {
                const targets = node.target || [];
                addOrUpdateMessage(ruleMessageText, messageType, true, node.html, targets, issue.tags);

                node.any.forEach(detail => {
                    const detailMessageText = detail.message;
                    addOrUpdateMessage(detailMessageText, messageType, false, node.html, targets, issue.tags);
                });

                const nodeId = getOrCreateNodeId(node.html, targets); 
                const nodeInStream = streamData.nodes.find(n => n.nodeId === nodeId);
                if (nodeInStream) {
                    nodeInStream.equalified = (messageType === 'pass');
                }
            });
        });
    };

    if (axeResults.results.violations) {
        processIssues(axeResults.results.violations, 'violation');
    }
    if (axeResults.results.incomplete) {
        processIssues(axeResults.results.incomplete, 'error');
    }
    if (axeResults.results.passes) {
        processIssues(axeResults.results.passes, 'pass');
    }

    return streamData;
}

module.exports = convertAxeResultsToStream;