Skip to content

test: add selector validation edge case tests#1072

Open
okwn wants to merge 1 commit into
getmaxun:developfrom
okwn:contrib/maxun/selector-validation
Open

test: add selector validation edge case tests#1072
okwn wants to merge 1 commit into
getmaxun:developfrom
okwn:contrib/maxun/selector-validation

Conversation

@okwn
Copy link
Copy Markdown

@okwn okwn commented May 21, 2026

Summary

  • Added comprehensive edge case tests for CSS selector validation logic in server/src/sdk/tests/selector-validation.test.ts
  • Tests cover empty strings, very long selectors, special characters, unicode, XPath, and whitespace handling

Problem

  • Selector validation lacked edge case test coverage
  • Potential issues with DOM-breaking characters, unicode, and malformed selectors were unverified

Solution

  • Added test file with 15+ test cases covering various selector edge cases
  • Uses Jest with mocked Page interface for isolation

Tests

npm test -- --testPathPattern=selector-validation

Risk / Compatibility

  • Risk: LOW
  • Affects: tests only

Summary by CodeRabbit

  • Tests
    • Enhanced test coverage for selector validation, including edge cases with special characters, unicode, and various selector formats to ensure reliability and robustness.

Review Change Stack

Add comprehensive tests for CSS selector validation edge cases:
- Empty string selector
- Very long selector strings
- Special characters that could break DOM
- Unicode characters in selectors
- XPath selectors
- Selectors with quotes, whitespace, newlines

Risk: LOW - tests only
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 21, 2026

Walkthrough

A new Jest test file adds comprehensive test coverage for SelectorValidator, exercising validateSelector across edge cases and error paths, testing validateSchemaFields for initialization and empty input scenarios, and validating detectInputType rejection behavior with a mocked Page object.

Changes

SelectorValidator test coverage

Layer / File(s) Summary
Mock Page factory and validateSelector test suite
server/src/sdk/__tests__/selector-validation.test.ts
Jest mock Page factory provides mocked locator, goto, click, and evaluate behaviors. validateSelector tests cover edge cases: empty selector, very long selector, special characters, unicode, XPath selectors, valid CSS selectors, quotes, whitespace/newlines, IDs with special characters, and comma-separated selectors. Initialization failure path is also tested.
validateSchemaFields test coverage
server/src/sdk/__tests__/selector-validation.test.ts
Tests for uninitialized browser error path and empty fields input, asserting valid: true and enriched: {} for empty input.
detectInputType test coverage
server/src/sdk/__tests__/selector-validation.test.ts
Tests for rejection behavior when browser is not initialized and when selector matching yields no results.

🎯 2 (Simple) | ⏱️ ~12 minutes

Suggested reviewers

  • amhsirak

Poem

🐰 Test coverage hops along with glee,
Validators checked, edge cases free!
Mock pages dance, selectors align,
Jest assertions all beautifully shine.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'test: add selector validation edge case tests' is fully related to the main change—adding comprehensive Jest test coverage for selector validation edge cases.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@server/src/sdk/__tests__/selector-validation.test.ts`:
- Around line 41-47: The current tests in selector-validation.test.ts only
assert the shape of the validator.validateSelector result; update each affected
test (e.g., the case using longSelector and other cases around validateSelector
calls at the mentioned blocks) to assert concrete expectations instead of just
keys: check result.valid is true or false as appropriate for the input, and
assert error is null/undefined for valid cases or contains the expected
message/substring/code for invalid cases; locate calls to
validator.validateSelector and variables like longSelector and replace the
generic expect(result).toHaveProperty(...) assertions with explicit expects on
result.valid and result.error semantics to validate correct behavior for each
edge case.
- Around line 9-22: The locator mock in createMockPage always returns the same
mockLocator, so selector-specific failures aren’t exercised; update
createMockPage so the locator jest.fn() accepts a selector argument and returns
different mockLocator objects or behaviors based on that selector (e.g., return
a mockLocator whose count() resolves 0 or whose evaluate() throws for invalid
selectors, and a successful mockLocator for valid selectors). Reference
createMockPage, locator, mockLocator, count, and evaluate when implementing
selector-aware branching so tests for malformed selectors hit the failure paths.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9de5ecc0-be4d-478c-b84c-007543c040bc

📥 Commits

Reviewing files that changed from the base of the PR and between 3263dca and 8965889.

📒 Files selected for processing (1)
  • server/src/sdk/__tests__/selector-validation.test.ts

Comment on lines +9 to +22
const createMockPage = () => {
const mockLocator = {
first: () => mockLocator,
count: jest.fn().mockResolvedValue(0),
evaluate: jest.fn().mockResolvedValue('DIV'),
};
return {
locator: jest.fn().mockReturnValue(mockLocator),
goto: jest.fn().mockResolvedValue(undefined),
waitForTimeout: jest.fn().mockResolvedValue(undefined),
click: jest.fn().mockResolvedValue(undefined),
waitForSelector: jest.fn().mockResolvedValue(undefined),
evaluate: jest.fn().mockResolvedValue(undefined),
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Make locator mock selector-aware to avoid false positives.

Right now (Line 16) every selector returns the same successful locator path, so malformed selector tests don’t exercise failure behavior at all.

Proposed adjustment
-    locator: jest.fn().mockReturnValue(mockLocator),
+    locator: jest.fn((selector: string) => {
+      if (!selector.trim()) throw new Error('Invalid selector');
+      if (selector.includes('<script>') || selector.includes('::before{')) {
+        throw new Error('Invalid selector');
+      }
+      return mockLocator;
+    }),
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const createMockPage = () => {
const mockLocator = {
first: () => mockLocator,
count: jest.fn().mockResolvedValue(0),
evaluate: jest.fn().mockResolvedValue('DIV'),
};
return {
locator: jest.fn().mockReturnValue(mockLocator),
goto: jest.fn().mockResolvedValue(undefined),
waitForTimeout: jest.fn().mockResolvedValue(undefined),
click: jest.fn().mockResolvedValue(undefined),
waitForSelector: jest.fn().mockResolvedValue(undefined),
evaluate: jest.fn().mockResolvedValue(undefined),
};
const createMockPage = () => {
const mockLocator = {
first: () => mockLocator,
count: jest.fn().mockResolvedValue(0),
evaluate: jest.fn().mockResolvedValue('DIV'),
};
return {
locator: jest.fn((selector: string) => {
if (!selector.trim()) throw new Error('Invalid selector');
if (selector.includes('<script>') || selector.includes('::before{')) {
throw new Error('Invalid selector');
}
return mockLocator;
}),
goto: jest.fn().mockResolvedValue(undefined),
waitForTimeout: jest.fn().mockResolvedValue(undefined),
click: jest.fn().mockResolvedValue(undefined),
waitForSelector: jest.fn().mockResolvedValue(undefined),
evaluate: jest.fn().mockResolvedValue(undefined),
};
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/src/sdk/__tests__/selector-validation.test.ts` around lines 9 - 22,
The locator mock in createMockPage always returns the same mockLocator, so
selector-specific failures aren’t exercised; update createMockPage so the
locator jest.fn() accepts a selector argument and returns different mockLocator
objects or behaviors based on that selector (e.g., return a mockLocator whose
count() resolves 0 or whose evaluate() throws for invalid selectors, and a
successful mockLocator for valid selectors). Reference createMockPage, locator,
mockLocator, count, and evaluate when implementing selector-aware branching so
tests for malformed selectors hit the failure paths.

Comment on lines +41 to +47
it('should handle very long selector strings', async () => {
const longSelector = 'div'.repeat(10000);
// Should not throw, should return valid or invalid gracefully
const result = await validator.validateSelector({ selector: longSelector });
expect(result).toHaveProperty('valid');
expect(result).toHaveProperty('error');
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Strengthen assertions to validate behavior, not just object shape.

These checks mostly verify keys exist, so they don’t confirm correctness for each edge case. Please assert explicit outcomes (valid true/false and expected error semantics) per scenario.

Example assertion upgrade pattern
-      expect(result).toHaveProperty('valid');
-      expect(result).toHaveProperty('error');
+      expect(result.valid).toBe(true);
+      expect(result.error).toBeUndefined();
-      expect(result).toHaveProperty('valid');
-      expect(result).toHaveProperty('error');
+      expect(result.valid).toBe(false);
+      expect(result.error).toBeDefined();

Also applies to: 57-63, 74-79, 95-97, 104-107, 114-116, 123-125, 132-133, 140-142

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/src/sdk/__tests__/selector-validation.test.ts` around lines 41 - 47,
The current tests in selector-validation.test.ts only assert the shape of the
validator.validateSelector result; update each affected test (e.g., the case
using longSelector and other cases around validateSelector calls at the
mentioned blocks) to assert concrete expectations instead of just keys: check
result.valid is true or false as appropriate for the input, and assert error is
null/undefined for valid cases or contains the expected message/substring/code
for invalid cases; locate calls to validator.validateSelector and variables like
longSelector and replace the generic expect(result).toHaveProperty(...)
assertions with explicit expects on result.valid and result.error semantics to
validate correct behavior for each edge case.

@amhsirak amhsirak added the Status: In Review This PR/issue is being reviewed label May 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Status: In Review This PR/issue is being reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants