9b395f5cc3
E2E Headed Chrome / e2e-headed (macos-15) (push) Has been cancelled
E2E Headed Chrome / e2e-headed (ubuntu-latest) (push) Has been cancelled
E2E Headed Chrome / e2e-headed (windows-latest) (push) Has been cancelled
CI / build (macos-latest) (push) Has been cancelled
CI / build (ubuntu-latest) (push) Has been cancelled
CI / build (windows-latest) (push) Has been cancelled
CI / unit-test (push) Has been cancelled
CI / bun-test (push) Has been cancelled
CI / adapter-test (push) Has been cancelled
CI / smoke-test (macos-latest) (push) Has been cancelled
CI / smoke-test (ubuntu-latest) (push) Has been cancelled
Security Audit / audit (push) Has been cancelled
Build Chrome Extension / build (push) Has been cancelled
Trigger Website Rebuild (Docs Updated) / dispatch (push) Has been cancelled
109 lines
5.3 KiB
JavaScript
109 lines
5.3 KiB
JavaScript
import { describe, expect, it } from 'vitest';
|
|
import { CommandExecutionError } from '@jackwener/opencli/errors';
|
|
import {
|
|
requireArrayEvaluateResult,
|
|
requireBooleanEvaluateResult,
|
|
requireObjectEvaluateResult,
|
|
unwrapEvaluateResult,
|
|
} from './utils.js';
|
|
|
|
describe('chatgpt page.evaluate envelope helpers', () => {
|
|
describe('unwrapEvaluateResult', () => {
|
|
it('unwraps a { session, data } envelope produced by the browser bridge', () => {
|
|
const envelope = { session: 'site:chatgpt:abc', data: [{ id: 'msg-1' }] };
|
|
expect(unwrapEvaluateResult(envelope)).toEqual([{ id: 'msg-1' }]);
|
|
});
|
|
|
|
it('passes raw arrays through unchanged (back-compat with older bridge versions)', () => {
|
|
const raw = [1, 2, 3];
|
|
expect(unwrapEvaluateResult(raw)).toBe(raw);
|
|
});
|
|
|
|
it('passes primitive return values (URL strings, booleans) through unchanged', () => {
|
|
expect(unwrapEvaluateResult('https://chatgpt.com/c/abc')).toBe('https://chatgpt.com/c/abc');
|
|
expect(unwrapEvaluateResult(true)).toBe(true);
|
|
expect(unwrapEvaluateResult(0)).toBe(0);
|
|
});
|
|
|
|
it('passes plain non-envelope objects through unchanged', () => {
|
|
const obj = { ok: true, reason: 'all good' };
|
|
expect(unwrapEvaluateResult(obj)).toBe(obj);
|
|
});
|
|
|
|
it('handles null and undefined defensively', () => {
|
|
expect(unwrapEvaluateResult(null)).toBe(null);
|
|
expect(unwrapEvaluateResult(undefined)).toBe(undefined);
|
|
});
|
|
});
|
|
|
|
describe('requireArrayEvaluateResult', () => {
|
|
it('returns the payload when it is an array', () => {
|
|
const rows = [{ id: 1 }, { id: 2 }];
|
|
expect(requireArrayEvaluateResult(rows, 'chatgpt test')).toBe(rows);
|
|
});
|
|
|
|
it('throws a typed CommandExecutionError when the payload is the raw envelope (caller forgot to unwrap)', () => {
|
|
const envelope = { session: 'site:chatgpt:abc', data: [{ id: 1 }] };
|
|
expect(() => requireArrayEvaluateResult(envelope, 'chatgpt visible image url extraction'))
|
|
.toThrowError(CommandExecutionError);
|
|
expect(() => requireArrayEvaluateResult(envelope, 'chatgpt visible image url extraction'))
|
|
.toThrow(/malformed extraction payload/);
|
|
});
|
|
|
|
it('surfaces the inner error message when the payload carries an `error` field', () => {
|
|
const errPayload = { error: 'image generator returned 500' };
|
|
expect(() => requireArrayEvaluateResult(errPayload, 'chatgpt image asset export'))
|
|
.toThrow(/chatgpt image asset export: image generator returned 500/);
|
|
});
|
|
|
|
it('throws when the payload is null or a primitive', () => {
|
|
expect(() => requireArrayEvaluateResult(null, 'chatgpt test')).toThrowError(CommandExecutionError);
|
|
expect(() => requireArrayEvaluateResult('a string', 'chatgpt test')).toThrowError(CommandExecutionError);
|
|
});
|
|
});
|
|
|
|
describe('requireObjectEvaluateResult', () => {
|
|
it('returns the payload when it is a plain object', () => {
|
|
const obj = { url: 'https://chatgpt.com', isLoggedIn: true };
|
|
expect(requireObjectEvaluateResult(obj, 'chatgpt page state')).toBe(obj);
|
|
});
|
|
|
|
it('throws when the payload is an array or a primitive', () => {
|
|
expect(() => requireObjectEvaluateResult([], 'chatgpt page state')).toThrowError(CommandExecutionError);
|
|
expect(() => requireObjectEvaluateResult('string', 'chatgpt page state')).toThrowError(CommandExecutionError);
|
|
expect(() => requireObjectEvaluateResult(null, 'chatgpt page state')).toThrowError(CommandExecutionError);
|
|
});
|
|
});
|
|
|
|
describe('requireBooleanEvaluateResult', () => {
|
|
it('returns booleans and rejects wrong-shape values', () => {
|
|
expect(requireBooleanEvaluateResult(true, 'chatgpt generation state')).toBe(true);
|
|
expect(requireBooleanEvaluateResult(false, 'chatgpt generation state')).toBe(false);
|
|
expect(() => requireBooleanEvaluateResult({ ok: true }, 'chatgpt generation state'))
|
|
.toThrowError(CommandExecutionError);
|
|
});
|
|
});
|
|
|
|
describe('end-to-end envelope sweep', () => {
|
|
// The bridge envelope is shaped like { session, data } where `session` is
|
|
// any string and `data` is the actual return value. Verify the helpers
|
|
// chain correctly: unwrap → require* yields the inner shape.
|
|
it('unwrap + requireArray pipes an envelope through to the underlying array', () => {
|
|
const envelope = {
|
|
session: 'site:chatgpt:img-export',
|
|
data: [
|
|
{ url: 'https://a.example/1.png', dataUrl: 'data:image/png;base64,xxx', mimeType: 'image/png' },
|
|
],
|
|
};
|
|
expect(requireArrayEvaluateResult(unwrapEvaluateResult(envelope), 'chatgpt image asset export'))
|
|
.toEqual(envelope.data);
|
|
});
|
|
|
|
it('unwrap + requireObject pipes an envelope through to the underlying object', () => {
|
|
const envelope = { session: 'site:chatgpt:state', data: { url: 'https://chatgpt.com', isLoggedIn: true } };
|
|
expect(requireObjectEvaluateResult(unwrapEvaluateResult(envelope), 'chatgpt page state'))
|
|
.toEqual(envelope.data);
|
|
});
|
|
});
|
|
});
|