Skip to main content
Glama
by Ritesh-sudo
extract.spec.ts7.43 kB
import { describe, it, expect, expectTypeOf } from 'vitest'; import * as fixtures from '../__fixtures__/fixtures.js'; import { load } from '../load-parse.js'; interface RedSelObject { red: string | undefined; sel: string | undefined; } interface RedSelMultipleObject { red: string[]; sel: string[]; } describe('$.extract', () => { it('should return an empty object when no selectors are provided', () => { const $ = load(fixtures.eleven); const $root = $.root(); expectTypeOf($root.extract({})).toEqualTypeOf<Record<never, never>>(); const emptyExtract = $root.extract({}); expect(emptyExtract).toStrictEqual({}); }); it('should return undefined for selectors that do not match any elements', () => { const $ = load(fixtures.eleven); const $root = $.root(); expectTypeOf($root.extract({ foo: 'bar' })).toEqualTypeOf<{ foo: string | undefined; }>(); const simpleExtract = $root.extract({ foo: 'bar' }); expect(simpleExtract).toStrictEqual({ foo: undefined }); }); it('should extract values for existing selectors', () => { const $ = load(fixtures.eleven); const $root = $.root(); expectTypeOf($root.extract({ red: '.red' })).toEqualTypeOf<{ red: string | undefined; }>(); expect($root.extract({ red: '.red' })).toStrictEqual({ red: 'Four' }); expectTypeOf( $root.extract({ red: '.red', sel: '.sel' }), ).toEqualTypeOf<RedSelObject>(); expect($root.extract({ red: '.red', sel: '.sel' })).toStrictEqual({ red: 'Four', sel: 'Three', }); }); it('should extract values using descriptor objects', () => { const $ = load(fixtures.eleven); const $root = $.root(); expectTypeOf( $root.extract({ red: { selector: '.red' }, sel: { selector: '.sel' }, }), ).toEqualTypeOf<RedSelObject>(); expect( $root.extract({ red: { selector: '.red' }, sel: { selector: '.sel' }, }), ).toStrictEqual({ red: 'Four', sel: 'Three' }); }); it('should extract multiple values for selectors', () => { const $ = load(fixtures.eleven); const $root = $.root(); expectTypeOf( $root.extract({ red: ['.red'], sel: ['.sel'], }), ).toEqualTypeOf<{ red: string[]; sel: string[] }>(); const multipleExtract = $root.extract({ red: ['.red'], sel: ['.sel'], }); expectTypeOf(multipleExtract).toEqualTypeOf<RedSelMultipleObject>(); expect(multipleExtract).toStrictEqual({ red: ['Four', 'Five', 'Nine'], sel: ['Three', 'Nine', 'Eleven'], }); }); it('should extract custom properties specified by the user', () => { const $ = load(fixtures.eleven); const $root = $.root(); expectTypeOf( $root.extract({ red: { selector: '.red', value: 'outerHTML' }, sel: { selector: '.sel', value: 'tagName' }, }), ).toEqualTypeOf<RedSelObject>(); expect( $root.extract({ red: { selector: '.red', value: 'outerHTML' }, sel: { selector: '.sel', value: 'tagName' }, }), ).toStrictEqual({ red: '<li class="red">Four</li>', sel: 'LI' }); }); it('should extract multiple custom properties for selectors', () => { const $ = load(fixtures.eleven); const $root = $.root(); expectTypeOf( $root.extract({ red: [{ selector: '.red', value: 'outerHTML' }], }), ).toEqualTypeOf<{ red: string[] }>(); expect( $root.extract({ red: [{ selector: '.red', value: 'outerHTML' }], }), ).toStrictEqual({ red: [ '<li class="red">Four</li>', '<li class="red">Five</li>', '<li class="red sel">Nine</li>', ], }); }); it('should extract values using custom extraction functions', () => { const $ = load(fixtures.eleven); const $root = $.root(); expectTypeOf( $root.extract({ red: { selector: '.red', value: (el, key) => `${key}=${$(el).text()}`, }, }), ).toEqualTypeOf<{ red: string | undefined }>(); expect( $root.extract({ red: { selector: '.red', value: (el, key) => `${key}=${$(el).text()}`, }, }), ).toStrictEqual({ red: 'red=Four' }); }); it('should correctly type check custom extraction functions returning non-string values', () => { const $ = load(fixtures.eleven); const $root = $.root(); expectTypeOf( $root.extract({ red: { selector: '.red', value: (el) => $(el).text().length, }, }), ).toEqualTypeOf<{ red: number | undefined }>(); expect( $root.extract({ red: { selector: '.red', value: (el) => $(el).text().length, }, }), ).toStrictEqual({ red: 4 }); }); it('should extract multiple values using custom extraction functions', () => { const $ = load(fixtures.eleven); const $root = $.root(); expectTypeOf( $root.extract({ red: [ { selector: '.red', value: (el, key) => `${key}=${$(el).text()}`, }, ], }), ).toEqualTypeOf<{ red: string[] }>(); expect( $root.extract({ red: [ { selector: '.red', value: (el, key) => `${key}=${$(el).text()}`, }, ], }), ).toStrictEqual({ red: ['red=Four', 'red=Five', 'red=Nine'] }); }); it('should extract nested objects based on selectors', () => { const $ = load(fixtures.eleven); const $root = $.root(); expectTypeOf( $root.extract({ section: { selector: 'ul:nth(1)', value: { red: '.red', sel: '.blue', }, }, }), ).toEqualTypeOf<{ section: { red: string | undefined; sel: string | undefined } | undefined; }>(); const subExtractObject = $root.extract({ section: { selector: 'ul:nth(1)', value: { red: '.red', sel: '.blue', }, }, }); expectTypeOf(subExtractObject).toEqualTypeOf<{ section: RedSelObject | undefined; }>(); expect(subExtractObject).toStrictEqual({ section: { red: 'Five', sel: 'Seven', }, }); }); it('should correctly type check nested objects returning non-string values', () => { const $ = load(fixtures.eleven); const $root = $.root(); expectTypeOf( $root.extract({ section: { selector: 'ul:nth(1)', value: { red: { selector: '.red', value: (el) => $(el).text().length, }, }, }, }), ).toEqualTypeOf<{ section: { red: number | undefined } | undefined; }>(); expect( $root.extract({ section: { selector: 'ul:nth(1)', value: { red: { selector: '.red', value: (el) => $(el).text().length, }, }, }, }), ).toStrictEqual({ section: { red: 4, }, }); }); it('should handle missing href properties without errors (#4239)', () => { const $ = load(fixtures.eleven); expect<{ links: string[] }>( $.extract({ links: [{ selector: 'li', value: 'href' }] }), ).toStrictEqual({ links: [] }); }); });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Ritesh-sudo/MCPJobSearch'

If you have feedback or need assistance with the MCP directory API, please join our Discord server