mirror of
https://github.com/n8n-io/n8n.git
synced 2026-10-19 16:55:02 +02:00
fix(core): Support element refs when capturing browser secrets (no-changelog) (backport to release-candidate/2.29.x) (#33661)
Co-authored-by: Bernhard Wittmann <bernhard.wittmann@n8n.io>
This commit is contained in:
parent
34a8a71dfd
commit
bfa8db7045
|
|
@ -0,0 +1,85 @@
|
|||
import type { Page } from 'playwright-core';
|
||||
|
||||
import { PlaywrightAdapter } from './playwright';
|
||||
import { configureLogger } from '../logger';
|
||||
import type { ResolvedConfig } from '../types';
|
||||
|
||||
configureLogger({ level: 'silent' });
|
||||
|
||||
const config: ResolvedConfig = {
|
||||
defaultBrowser: 'chrome',
|
||||
browsers: new Map(),
|
||||
adapter: 'playwright',
|
||||
mode: 'local',
|
||||
};
|
||||
|
||||
interface FakeLocator {
|
||||
count: ReturnType<typeof vi.fn>;
|
||||
inputValue: ReturnType<typeof vi.fn>;
|
||||
innerText: ReturnType<typeof vi.fn>;
|
||||
}
|
||||
|
||||
function adapterWithLocator(pageId: string, locator: FakeLocator): PlaywrightAdapter {
|
||||
const adapter = new PlaywrightAdapter(config);
|
||||
const page = {
|
||||
locator: vi.fn().mockReturnValue(locator),
|
||||
} as unknown as Page;
|
||||
const pageStates = (adapter as unknown as { pageStates: Map<string, { page: Page }> }).pageStates;
|
||||
pageStates.set(pageId, { page });
|
||||
return adapter;
|
||||
}
|
||||
|
||||
describe('PlaywrightAdapter.getElementValue', () => {
|
||||
it('returns the live input value for a ref target', async () => {
|
||||
const locator: FakeLocator = {
|
||||
count: vi.fn().mockResolvedValue(1),
|
||||
inputValue: vi.fn().mockResolvedValue('xoxb-signing-secret'),
|
||||
innerText: vi.fn(),
|
||||
};
|
||||
const adapter = adapterWithLocator('p1', locator);
|
||||
|
||||
const value = await adapter.getElementValue('p1', { ref: 'e5' });
|
||||
|
||||
expect(value).toBe('xoxb-signing-secret');
|
||||
expect(locator.inputValue).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('falls back to inner text when the element is not an input', async () => {
|
||||
const locator: FakeLocator = {
|
||||
count: vi.fn().mockResolvedValue(1),
|
||||
inputValue: vi.fn().mockRejectedValue(new Error('Node is not an <input>')),
|
||||
innerText: vi.fn().mockResolvedValue('secret-in-code-block'),
|
||||
};
|
||||
const adapter = adapterWithLocator('p1', locator);
|
||||
|
||||
const value = await adapter.getElementValue('p1', { ref: 'e5' });
|
||||
|
||||
expect(value).toBe('secret-in-code-block');
|
||||
});
|
||||
|
||||
it('falls back to inner text when the input value is empty', async () => {
|
||||
const locator: FakeLocator = {
|
||||
count: vi.fn().mockResolvedValue(1),
|
||||
inputValue: vi.fn().mockResolvedValue(''),
|
||||
innerText: vi.fn().mockResolvedValue('text-content'),
|
||||
};
|
||||
const adapter = adapterWithLocator('p1', locator);
|
||||
|
||||
const value = await adapter.getElementValue('p1', { ref: 'e5' });
|
||||
|
||||
expect(value).toBe('text-content');
|
||||
});
|
||||
|
||||
it('reads the value for a selector target', async () => {
|
||||
const locator: FakeLocator = {
|
||||
count: vi.fn().mockResolvedValue(1),
|
||||
inputValue: vi.fn().mockResolvedValue('from-selector'),
|
||||
innerText: vi.fn(),
|
||||
};
|
||||
const adapter = adapterWithLocator('p1', locator);
|
||||
|
||||
const value = await adapter.getElementValue('p1', { selector: '#token' });
|
||||
|
||||
expect(value).toBe('from-selector');
|
||||
});
|
||||
});
|
||||
|
|
@ -1039,8 +1039,16 @@ export class PlaywrightAdapter {
|
|||
}
|
||||
}
|
||||
|
||||
getElementValue(_pageId: string, _target: ElementTarget): never {
|
||||
throw new Error('Not implemented');
|
||||
async getElementValue(pageId: string, target: ElementTarget): Promise<string> {
|
||||
const locator = await this.resolveLocator(pageId, target);
|
||||
let value = '';
|
||||
try {
|
||||
value = await locator.inputValue();
|
||||
} catch {
|
||||
// Not an <input>/<textarea>/<select>.
|
||||
}
|
||||
if (value !== '') return value;
|
||||
return await locator.innerText();
|
||||
}
|
||||
|
||||
private async resolveLocator(pageId: string, target: ElementTarget): Promise<Locator> {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user