/** * Tests for selector parsing library * Run with: node --test __tests__/selector.test.js */ import { describe, it } from 'node:test'; import assert from 'node:assert'; import { parseSelector } from '../lib/selector.js'; describe('parseSelector', () => { describe('CSS Selectors', () => { it('should detect simple CSS selectors', () => { const result = parseSelector('button'); assert.strictEqual(result.type, 'css'); assert.strictEqual(result.selector, 'button'); }); it('should detect class selectors', () => { const result = parseSelector('.btn-submit'); assert.strictEqual(result.type, 'css'); assert.strictEqual(result.selector, '.btn-submit'); }); it('should detect ID selectors', () => { const result = parseSelector('#email-input'); assert.strictEqual(result.type, 'css'); assert.strictEqual(result.selector, '#email-input'); }); it('should detect attribute selectors', () => { const result = parseSelector('button[type="submit"]'); assert.strictEqual(result.type, 'css'); assert.strictEqual(result.selector, 'button[type="submit"]'); }); it('should detect complex CSS selectors', () => { const result = parseSelector('div.container > button.btn-primary:hover'); assert.strictEqual(result.type, 'css'); }); }); describe('XPath Selectors', () => { it('should detect absolute XPath', () => { const result = parseSelector('/html/body/button'); assert.strictEqual(result.type, 'xpath'); assert.strictEqual(result.selector, '/html/body/button'); }); it('should detect relative XPath', () => { const result = parseSelector('//button'); assert.strictEqual(result.type, 'xpath'); assert.strictEqual(result.selector, '//button'); }); it('should detect XPath with text matching', () => { const result = parseSelector('//button[text()="Click Me"]'); assert.strictEqual(result.type, 'xpath'); }); it('should detect XPath with contains', () => { const result = parseSelector('//button[contains(text(),"Submit")]'); assert.strictEqual(result.type, 'xpath'); }); it('should detect XPath with attributes', () => { const result = parseSelector('//input[@type="email"]'); assert.strictEqual(result.type, 'xpath'); }); it('should detect grouped XPath', () => { const result = parseSelector('(//button)[1]'); assert.strictEqual(result.type, 'xpath'); }); }); describe('Security Validation', () => { it('should block javascript: injection', () => { assert.throws( () => parseSelector('//button[@onclick="javascript:alert(1)"]'), /XPath injection detected.*javascript:/i ); }); it('should block ")]'), /XPath injection detected.*