Skip to main content

JS Snippets & Workarounds

KaneAI's natural language engine handles the vast majority of web testing scenarios. However, some interactions require direct DOM manipulation or precise programmatic control that natural language can't reliably express. For these cases, KaneAI provides JS Snippets — the ability to execute JavaScript code directly on the page.

This guide is organized by common QA scenario, showing you when natural language falls short and exactly what JS snippet to use as a workaround.

How to Add a JS Snippet

  1. In the KaneAI input field, type / or click the + icon
  2. Select Add JS Snippet
  3. Write or paste your JavaScript code
  4. Click Add to execute it as a test step

The snippet runs in the context of the page and has full access to the DOM, document, window, and any JavaScript variables the page has defined.


Date Picker Interactions

Problem: Many date pickers use read-only inputs that reject typed values. Natural language typing doesn't trigger the custom event handlers these components rely on.

Set Date on a Read-Only Date Picker

const dateInput = document.querySelector('input[name="startDate"]');
// Remove readonly temporarily
dateInput.removeAttribute('readonly');
// Set the value
dateInput.value = '2026-03-15';
// Trigger change events so the framework (React, Angular, Vue) picks up the change
dateInput.dispatchEvent(new Event('input', { bubbles: true }));
dateInput.dispatchEvent(new Event('change', { bubbles: true }));
return 'Date set to 2026-03-15';

Set Date on React DatePicker

React components use synthetic events. Use the native input setter:

const dateInput = document.querySelector('input[name="date"]');
const nativeInputValueSetter = Object.getOwnPropertyDescriptor(
window.HTMLInputElement.prototype, 'value'
).set;
nativeInputValueSetter.call(dateInput, '2026-03-15');
dateInput.dispatchEvent(new Event('input', { bubbles: true }));
return 'React date picker value set';

Set Date Range Picker

const startDate = document.querySelector('input[name="start"]');
const endDate = document.querySelector('input[name="end"]');

const setter = Object.getOwnPropertyDescriptor(
window.HTMLInputElement.prototype, 'value'
).set;

setter.call(startDate, '2026-02-01');
startDate.dispatchEvent(new Event('input', { bubbles: true }));

setter.call(endDate, '2026-02-28');
endDate.dispatchEvent(new Event('input', { bubbles: true }));

return 'Date range set: Feb 1 - Feb 28, 2026';

String Manipulation & Data Transformation

Problem: Operations like converting text to lowercase, extracting substrings, or formatting data are not reliably handled via natural language.

Convert Text to Lowercase and Validate

const title = document.querySelector('h1.page-title').textContent;
const lowercase = title.toLowerCase();
if (lowercase === 'welcome to dashboard') {
return 'PASS: Title in lowercase matches expected value';
} else {
throw new Error('FAIL: Got "' + lowercase + '"');
}

Extract and Validate a Substring

const orderText = document.querySelector('.order-id').textContent;
// Text is "Order #12345" — extract just the number
const orderId = orderText.replace('Order #', '');
if (orderId.length === 5 && !isNaN(orderId)) {
return 'PASS: Order ID is valid: ' + orderId;
} else {
throw new Error('FAIL: Invalid order ID format: ' + orderId);
}

Trim Whitespace and Compare

const actual = document.querySelector('.username').textContent.trim();
const expected = 'john_doe';
if (actual === expected) {
return 'PASS: Username matches';
} else {
throw new Error('FAIL: Expected "' + expected + '", got "' + actual + '"');
}

Table & List Validation

Problem: KaneAI can't reliably assert specific cell values in complex tables (e.g., "the 5th column of the 3rd row contains X").

Assert Specific Table Cell Value

const rows = document.querySelectorAll('table.users-table tbody tr');
const thirdRowFifthCol = rows[2].querySelectorAll('td')[4].textContent.trim();
if (thirdRowFifthCol === 'Active') {
return 'PASS: 3rd row, 5th column is "Active"';
} else {
throw new Error('FAIL: Got "' + thirdRowFifthCol + '"');
}

Count Table Rows

const rowCount = document.querySelectorAll('table tbody tr').length;
if (rowCount === 10) {
return 'PASS: Table has 10 rows';
} else {
throw new Error('FAIL: Table has ' + rowCount + ' rows, expected 10');
}

Validate Table is Sorted

const cells = Array.from(document.querySelectorAll('table tbody tr td:first-child'));
const values = cells.map(cell => cell.textContent.trim());
const sorted = [...values].sort((a, b) => a.localeCompare(b));
const isSorted = JSON.stringify(values) === JSON.stringify(sorted);
if (isSorted) {
return 'PASS: Table is sorted alphabetically by first column';
} else {
throw new Error('FAIL: Table is not sorted. Got: ' + values.join(', '));
}

Clipboard Operations

Problem: Natural language can't directly read or write clipboard content.

Copy Text to Clipboard

const text = document.querySelector('.referral-code').textContent;
await navigator.clipboard.writeText(text);
return 'Copied to clipboard: ' + text;

Read Clipboard Content

const clipText = await navigator.clipboard.readText();
return 'Clipboard contains: ' + clipText;

Local Storage & Session Storage

Problem: You may need to verify, set, or clear browser storage for test setup or validation.

Read a Local Storage Value

const token = localStorage.getItem('authToken');
if (token) {
return 'Auth token exists: ' + token.substring(0, 20) + '...';
} else {
throw new Error('FAIL: No auth token in localStorage');
}

Set a Local Storage Value (Test Setup)

localStorage.setItem('feature_flag_newUI', 'true');
return 'Feature flag set';

Clear Session Storage (Logout Simulation)

sessionStorage.clear();
return 'Session storage cleared';

Quick Reference: When to Use JS Snippets

ScenarioNatural Language?JS Snippet Needed?
Click a visible buttonYesNo
Type in a standard inputYesNo
Assert text is visibleYesNo
Set date on read-only date pickerUnreliableYes
Validate specific table cellNoYes
String manipulation (lowercase, trim)UnreliableYes
Read/write localStorageNoYes
Clipboard operationsNoYes
Check if page is fully loadedNoYes
Count elements on pageUnreliable for exact countsYes

Best Practices for JS Snippets

PracticeDetails
Use natural language firstOnly fall back to JS when natural language is unreliable
Keep snippets focusedOne snippet = one action or assertion
Use descriptive return valuesReturn "PASS: ..." or throw "FAIL: ..." for clear test output
Null-check elementsAlways check if querySelector returns null before operating on it
Test snippets in browser DevTools firstPaste into the Console to verify before adding to KaneAI

Test across 3000+ combinations of browsers, real devices & OS.

Book Demo

Help and Support

Related Articles