testronaut 2.0.2 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/TODO.md
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
## Browser Automation Follow-Ups
|
|
13
13
|
|
|
14
14
|
- [x] Make `click_text` match exact text, prefer the innermost visible element, and fail quickly instead of clicking an ancestor or partial match.
|
|
15
|
+
- [ ] Replace framework/vendor-specific DOM class stripping with a framework-agnostic classifier that removes generated hashes, styling utilities, variants, and arbitrary selectors while preserving semantic component classes. Reconsider broad prefix rules such as `/^cl-/`, cap retained class count and length, and add representative fixtures for Tailwind, MUI, Ant Design, Chakra, Clerk, CSS Modules, and CSS-in-JS.
|
|
15
16
|
|
|
16
17
|
## Session and Reporting Follow-Ups
|
|
17
18
|
|
package/package.json
CHANGED
|
@@ -42,3 +42,31 @@ describe('ChromeBrowser.click_text', () => {
|
|
|
42
42
|
expect(browser.page.getByText).toHaveBeenCalledWith('Add', { exact: true });
|
|
43
43
|
});
|
|
44
44
|
});
|
|
45
|
+
|
|
46
|
+
describe('ChromeBrowser.check_text', () => {
|
|
47
|
+
it('reports text when at least one matching element is visible', async () => {
|
|
48
|
+
const matches = {
|
|
49
|
+
count: vi.fn().mockResolvedValue(2),
|
|
50
|
+
nth: vi.fn(index => [
|
|
51
|
+
{ isVisible: vi.fn().mockResolvedValue(false) },
|
|
52
|
+
{ isVisible: vi.fn().mockResolvedValue(true) },
|
|
53
|
+
][index]),
|
|
54
|
+
};
|
|
55
|
+
const browser = Object.create(ChromeBrowser.prototype);
|
|
56
|
+
browser.page = { getByText: vi.fn().mockReturnValue(matches) };
|
|
57
|
+
|
|
58
|
+
await expect(browser.check_text({ text: 'Signed out' })).resolves.toBe('FOUND: Signed out');
|
|
59
|
+
expect(browser.page.getByText).toHaveBeenCalledWith('Signed out');
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('does not report text that only exists in hidden elements', async () => {
|
|
63
|
+
const matches = {
|
|
64
|
+
count: vi.fn().mockResolvedValue(1),
|
|
65
|
+
nth: vi.fn().mockReturnValue({ isVisible: vi.fn().mockResolvedValue(false) }),
|
|
66
|
+
};
|
|
67
|
+
const browser = Object.create(ChromeBrowser.prototype);
|
|
68
|
+
browser.page = { getByText: vi.fn().mockReturnValue(matches) };
|
|
69
|
+
|
|
70
|
+
await expect(browser.check_text({ text: 'Hidden message' })).resolves.toBe('NOT FOUND: Hidden message');
|
|
71
|
+
});
|
|
72
|
+
});
|
|
@@ -285,7 +285,7 @@ describe('domControl helpers', () => {
|
|
|
285
285
|
const html = `
|
|
286
286
|
<button
|
|
287
287
|
id="btn"
|
|
288
|
-
class="text-sm bg-red-500 hover:bg-red-600 flex items-center btn-primary custom-class"
|
|
288
|
+
class="text-sm bg-red-500 hover:bg-red-600 disabled:opacity-50 [&_svg]:size-4 flex items-center btn-primary custom-class"
|
|
289
289
|
>
|
|
290
290
|
Click
|
|
291
291
|
</button>
|
|
@@ -301,6 +301,8 @@ describe('domControl helpers', () => {
|
|
|
301
301
|
expect(classes).not.toContain('text-sm');
|
|
302
302
|
expect(classes).not.toContain('bg-red-500');
|
|
303
303
|
expect(classes).not.toContain('hover:bg-red-600');
|
|
304
|
+
expect(classes).not.toContain('disabled:opacity-50');
|
|
305
|
+
expect(classes).not.toContain('[&_svg]:size-4');
|
|
304
306
|
expect(classes).not.toContain('flex');
|
|
305
307
|
expect(classes).not.toContain('items-center');
|
|
306
308
|
|
package/tools/chromeBrowser.js
CHANGED
|
@@ -1135,8 +1135,14 @@ export class ChromeBrowser {
|
|
|
1135
1135
|
|
|
1136
1136
|
|
|
1137
1137
|
async check_text({ text }) {
|
|
1138
|
-
const
|
|
1139
|
-
|
|
1138
|
+
const matches = this.page.getByText(text);
|
|
1139
|
+
const count = await matches.count();
|
|
1140
|
+
for (let index = 0; index < count; index++) {
|
|
1141
|
+
if (await matches.nth(index).isVisible().catch(() => false)) {
|
|
1142
|
+
return `FOUND: ${text}`;
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
return `NOT FOUND: ${text}`;
|
|
1140
1146
|
}
|
|
1141
1147
|
|
|
1142
1148
|
async click_text({ text, timeout = 3000 }) {
|
package/tools/domControl.js
CHANGED
|
@@ -271,7 +271,8 @@ export function removeAutoGeneratedClasses($) {
|
|
|
271
271
|
const $el = $(el);
|
|
272
272
|
const classes = ($el.attr('class') || '').split(/\s+/);
|
|
273
273
|
const filtered = classes.filter(cls => {
|
|
274
|
-
|
|
274
|
+
const isVariantOrArbitraryUtility = cls.includes(':') || cls.includes('[');
|
|
275
|
+
return !isVariantOrArbitraryUtility && !utilityClassPatterns.some(pattern => pattern.test(cls));
|
|
275
276
|
});
|
|
276
277
|
if (filtered.length) {
|
|
277
278
|
$el.attr('class', filtered.join(' '));
|
package/tools/toolSchema.js
CHANGED