ngx-speculoos 6.0.0 → 7.2.0

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.
Files changed (36) hide show
  1. package/README.md +403 -42
  2. package/esm2020/jasmine-matchers.mjs +2 -0
  3. package/esm2020/lib/component-tester.mjs +147 -0
  4. package/esm2020/lib/matchers.mjs +283 -0
  5. package/esm2020/lib/mock.mjs +25 -0
  6. package/esm2020/lib/route.mjs +319 -0
  7. package/{esm2015/lib/test-button.js → esm2020/lib/test-button.mjs} +0 -0
  8. package/esm2020/lib/test-element-querier.mjs +140 -0
  9. package/esm2020/lib/test-element.mjs +142 -0
  10. package/{esm2015/lib/test-html-element.js → esm2020/lib/test-html-element.mjs} +0 -0
  11. package/{esm2015/lib/test-input.js → esm2020/lib/test-input.mjs} +0 -0
  12. package/{esm2015/lib/test-select.js → esm2020/lib/test-select.mjs} +0 -0
  13. package/{esm2015/lib/test-textarea.js → esm2020/lib/test-textarea.mjs} +0 -0
  14. package/{esm2015/ngx-speculoos.js → esm2020/ngx-speculoos.mjs} +0 -0
  15. package/{esm2015/public_api.js → esm2020/public_api.mjs} +2 -1
  16. package/fesm2015/ngx-speculoos.mjs +1257 -0
  17. package/fesm2015/ngx-speculoos.mjs.map +1 -0
  18. package/{fesm2015/ngx-speculoos.js → fesm2020/ngx-speculoos.mjs} +436 -22
  19. package/fesm2020/ngx-speculoos.mjs.map +1 -0
  20. package/jasmine-matchers.d.ts +5 -0
  21. package/lib/component-tester.d.ts +87 -49
  22. package/lib/mock.d.ts +10 -0
  23. package/lib/route.d.ts +149 -0
  24. package/lib/test-element-querier.d.ts +15 -15
  25. package/lib/test-element.d.ts +87 -49
  26. package/package.json +24 -11
  27. package/public_api.d.ts +1 -0
  28. package/bundles/ngx-speculoos.umd.js +0 -1259
  29. package/bundles/ngx-speculoos.umd.js.map +0 -1
  30. package/esm2015/jasmine-matchers.js +0 -2
  31. package/esm2015/lib/component-tester.js +0 -96
  32. package/esm2015/lib/matchers.js +0 -244
  33. package/esm2015/lib/route.js +0 -81
  34. package/esm2015/lib/test-element-querier.js +0 -129
  35. package/esm2015/lib/test-element.js +0 -91
  36. package/fesm2015/ngx-speculoos.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ngx-speculoos.mjs","sources":["../../../projects/ngx-speculoos/src/lib/test-element.ts","../../../projects/ngx-speculoos/src/lib/test-html-element.ts","../../../projects/ngx-speculoos/src/lib/test-button.ts","../../../projects/ngx-speculoos/src/lib/test-select.ts","../../../projects/ngx-speculoos/src/lib/test-textarea.ts","../../../projects/ngx-speculoos/src/lib/test-input.ts","../../../projects/ngx-speculoos/src/lib/test-element-querier.ts","../../../projects/ngx-speculoos/src/lib/component-tester.ts","../../../projects/ngx-speculoos/src/lib/route.ts","../../../projects/ngx-speculoos/src/lib/matchers.ts","../../../projects/ngx-speculoos/src/lib/mock.ts","../../../projects/ngx-speculoos/src/public_api.ts","../../../projects/ngx-speculoos/src/ngx-speculoos.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { ComponentTester } from './component-tester';\nimport { TestButton } from './test-button';\nimport { TestSelect } from './test-select';\nimport { TestTextArea } from './test-textarea';\nimport { TestInput } from './test-input';\nimport { TestElementQuerier } from './test-element-querier';\nimport { DebugElement, ProviderToken, Type } from '@angular/core';\nimport { TestHtmlElement } from './test-html-element';\n\n/**\n * A wrapped DOM element, providing additional methods and attributes helping with writing tests\n */\nexport class TestElement<E extends Element = Element> {\n private querier: TestElementQuerier;\n\n constructor(\n protected tester: ComponentTester<unknown>,\n /**\n * the wrapped debug element\n */\n readonly debugElement: DebugElement\n ) {\n this.querier = new TestElementQuerier(tester, debugElement);\n }\n\n get nativeElement(): E {\n return this.debugElement.nativeElement;\n }\n\n /**\n * the text content of this element\n */\n get textContent(): string | null {\n return this.nativeElement.textContent;\n }\n\n /**\n * dispatches an event of the given type from the wrapped element, then triggers a change detection\n */\n dispatchEventOfType(type: string): void {\n this.nativeElement.dispatchEvent(new Event(type));\n this.tester.detectChanges();\n }\n\n /**\n * dispatches the given event from the wrapped element, then triggers a change detection\n */\n dispatchEvent(event: Event): void {\n this.nativeElement.dispatchEvent(event);\n this.tester.detectChanges();\n }\n\n /**\n * Gets the CSS classes of the wrapped element, as an array\n */\n get classes(): Array<string> {\n return Array.prototype.slice.call(this.nativeElement.classList);\n }\n\n /**\n * Gets the attribute of the wrapped element with the given name\n * @param name the name of the attribute to get\n */\n attr(name: string): string | null {\n return this.nativeElement.getAttribute(name);\n }\n\n /**\n * Gets the first element matching the given CSS selector and wraps it into a TestElement. The actual type\n * of the returned value is the TestElement subclass matching the type of the found element. So, if the\n * matched element is an input for example, the method will return a TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElement: TestHtmlElement&lt;HTMLDivElement> | null = tester.element('div');\n * </code>\n * @param selector a CSS selector\n * @returns the wrapped element, or null if no element matches the selector.\n */\n element<K extends keyof HTMLElementTagNameMap>(selector: K): TestHtmlElement<HTMLElementTagNameMap[K]> | null;\n /**\n * Gets the first element matching the given CSS selector and wraps it into a TestElement. The actual type\n * of the returned value is the TestElement subclass matching the type of the found element. So, if the\n * matched element is an input for example, the method will return a TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElement: TestElement&lt;SVGLineElement> | null = tester.element('line');\n * </code>\n * @param selector a CSS selector\n * @returns the wrapped element, or null if no element matches the selector.\n */\n element<K extends keyof SVGElementTagNameMap>(selector: K): TestElement<SVGElementTagNameMap[K]> | null;\n /**\n * Gets the first element matching the given CSS selector and wraps it into a TestElement. The actual type\n * of the returned value is the TestElement subclass matching the type of the found element. So, if the\n * matched element is an input for example, the method will return a TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElement: TestElement | null = tester.element('.selector');\n * </code>\n * @param selector a CSS or directive selector\n * @returns the wrapped element, or null if no element matches the selector.\n */\n element(selector: string | Type<any>): TestElement | null;\n /**\n * Gets the first element matching the given selector and wraps it into a TestElement. The actual type\n * of the returned value is the TestElement subclass matching the type of the found element. So, if the\n * matched element is an input for example, the method will return a TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElement: TestInput | null = tester.element&lt;HTMLInputElement>('.selector');\n * </code>\n * @param selector a CSS or directive selector\n * @returns the wrapped element, or null if no element matches the selector.\n */\n element<T extends HTMLInputElement>(selector: string | Type<any>): TestInput | null;\n /**\n * Gets the first element matching the given selector and wraps it into a TestElement. The actual type\n * of the returned value is the TestElement subclass matching the type of the found element. So, if the\n * matched element is an input for example, the method will return a TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElement: TestTextArea | null = tester.element&lt;HTMLTextAreaElement>('.selector');\n * </code>\n * @param selector a CSS or directive selector\n * @returns the wrapped element, or null if no element matches the selector.\n */\n element<T extends HTMLTextAreaElement>(selector: string | Type<any>): TestTextArea | null;\n /**\n * Gets the first element matching the given selector and wraps it into a TestElement. The actual type\n * of the returned value is the TestElement subclass matching the type of the found element. So, if the\n * matched element is an input for example, the method will return a TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElement: TestSelect | null = tester.element&lt;HTMLSelectElement>('.selector');\n * </code>\n * @param selector a CSS or directive selector\n * @returns the wrapped element, or null if no element matches the selector.\n */\n element<T extends HTMLSelectElement>(selector: string | Type<any>): TestSelect | null;\n /**\n * Gets the first element matching the given selector and wraps it into a TestElement. The actual type\n * of the returned value is the TestElement subclass matching the type of the found element. So, if the\n * matched element is an input for example, the method will return a TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElement: TestButton | null = tester.element&lt;HTMLButtonElement>('.selector');\n * </code>\n * @param selector a CSS or directive selector\n * @returns the wrapped element, or null if no element matches the selector.\n */\n element<T extends HTMLButtonElement>(selector: string | Type<any>): TestButton | null;\n /**\n * Gets the first element matching the given selector and wraps it into a TestElement. The actual type\n * of the returned value is the TestElement subclass matching the type of the found element. So, if the\n * matched element is an input for example, the method will return a TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElement: TestHtmlElement&lt;HTMLDivElement> | null = tester.element&lt;HTMLDivElement>('.selector');\n * </code>\n * @param selector a CSS or directive selector\n * @returns the wrapped element, or null if no element matches the selector.\n */\n element<T extends HTMLElement>(selector: string | Type<any>): TestHtmlElement<T> | null;\n /**\n * Gets the first element matching the given selector and wraps it into a TestElement. The actual type\n * of the returned value is the TestElement subclass matching the type of the found element. So, if the\n * matched element is an input for example, the method will return a TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElement: TestElement&lt;SVGLineElement> | null = tester.element&lt;SVGLineElement>('.selector');\n * </code>\n * @param selector a CSS or directive selector\n * @returns the wrapped element, or null if no element matches the selector.\n */\n element<T extends Element>(selector: string | Type<any>): TestElement<T> | null;\n element(selector: string | Type<any>): TestElement | null {\n return this.querier.element(selector);\n }\n\n /**\n * Gets all the elements matching the given CSS selector and wraps them into a TestElement. The actual type\n * of the returned elements is the TestElement subclass matching the type of the found element. So, if the\n * matched elements are inputs for example, the method will return an array of TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElements: Array&lt;TestHtmlElement&lt;HTMLDivElement>> = tester.elements('div');\n * </code>\n * @param selector a CSS selector\n * @returns the array of matched elements, empty if no element was matched\n */\n elements<K extends keyof HTMLElementTagNameMap>(selector: K): Array<TestHtmlElement<HTMLElementTagNameMap[K]>>;\n /**\n * Gets all the elements matching the given CSS selector and wraps them into a TestElement. The actual type\n * of the returned elements is the TestElement subclass matching the type of the found element. So, if the\n * matched elements are inputs for example, the method will return an array of TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElements: Array&lt;TestElement&lt;SVGLineElement>> = tester.elements('line');\n * </code>\n * @param selector a CSS selector\n * @returns the array of matched elements, empty if no element was matched\n */\n elements<K extends keyof SVGElementTagNameMap>(selector: K): Array<TestElement<SVGElementTagNameMap[K]>>;\n /**\n * Gets all the elements matching the given selector and wraps them into a TestElement. The actual type\n * of the returned elements is the TestElement subclass matching the type of the found element. So, if the\n * matched elements are inputs for example, the method will return an array of TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElements: Array&lt;TestElement> = tester.elements('.selector');\n * </code>\n * @param selector a CSS or directive selector\n * @returns the array of matched elements, empty if no element was matched\n */\n elements(selector: string | Type<any>): Array<TestElement>;\n /**\n * Gets all the elements matching the given selector and wraps them into a TestElement. The actual type\n * of the returned elements is the TestElement subclass matching the type of the found element. So, if the\n * matched elements are inputs for example, the method will return an array of TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElements: Array&lt;TestInput> = tester.elements&lt;HTMLInputElement>('.selector');\n * </code>\n * @param selector a CSS or directive selector\n * @returns the array of matched elements, empty if no element was matched\n */\n elements<T extends HTMLInputElement>(selector: string | Type<any>): Array<TestInput>;\n /**\n * Gets all the elements matching the given selector and wraps them into a TestElement. The actual type\n * of the returned elements is the TestElement subclass matching the type of the found element. So, if the\n * matched elements are inputs for example, the method will return an array of TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElements: Array&lt;TestTextArea> = tester.elements&lt;HTMLTextAreaElement>('.selector');\n * </code>\n * @param selector a CSS or directive selector\n * @returns the array of matched elements, empty if no element was matched\n */\n elements<T extends HTMLTextAreaElement>(selector: string | Type<any>): Array<TestTextArea>;\n /**\n * Gets all the elements matching the given CSS selector and wraps them into a TestElement. The actual type\n * of the returned elements is the TestElement subclass matching the type of the found element. So, if the\n * matched elements are inputs for example, the method will return an array of TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElements: Array&lt;TestButton> = tester.elements&lt;HTMLButtonElement>('.selector');\n * </code>\n * @param selector a CSS or directive selector\n * @returns the array of matched elements, empty if no element was matched\n */\n elements<T extends HTMLButtonElement>(selector: string | Type<any>): Array<TestButton>;\n /**\n * Gets all the elements matching the given selector and wraps them into a TestElement. The actual type\n * of the returned elements is the TestElement subclass matching the type of the found element. So, if the\n * matched elements are inputs for example, the method will return an array of TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElements: Array&lt;TestSelect> = tester.elements<HTMLSelectElement>('.selector');\n * </code>\n * @param selector a CSS or directive selector\n * @returns the array of matched elements, empty if no element was matched\n */\n elements<T extends HTMLSelectElement>(selector: string | Type<any>): Array<TestSelect>;\n /**\n * Gets all the elements matching the given selector and wraps them into a TestElement. The actual type\n * of the returned elements is the TestElement subclass matching the type of the found element. So, if the\n * matched elements are inputs for example, the method will return an array of TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElements: Array&lt;TestHtmlElement&lt;HTMLDivElement>> = tester.elements&lt;HTMLDivElement>('.selector');\n * </code>\n * @param selector a CSS or directive selector\n * @returns the array of matched elements, empty if no element was matched\n */\n elements<T extends HTMLElement>(selector: string | Type<any>): Array<TestHtmlElement<T>>;\n /**\n * Gets all the elements matching the given selector and wraps them into a TestElement. The actual type\n * of the returned elements is the TestElement subclass matching the type of the found element. So, if the\n * matched elements are inputs for example, the method will return an array of TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElements: Array&lt;TestElement&lt;SVGLineElement>> = tester.elements&lt;SVGLineElement>('.selector');\n * </code>\n * @param selector a CSS or directive selector\n * @returns the array of matched elements, empty if no element was matched\n */\n elements<T extends Element>(selector: string | Type<any>): Array<TestElement<T>>;\n elements(selector: string | Type<any>): Array<TestElement> {\n return this.querier.elements(selector);\n }\n\n /**\n * Gets the first input matched by the given selector. Throws an Error if the matched element isn't actually an input.\n * @param selector a CSS or directive selector\n * @returns the wrapped input, or null if no element was matched\n */\n input(selector: string | Type<any>): TestInput | null {\n return this.querier.input(selector);\n }\n\n /**\n * Gets the first select matched by the given selector. Throws an Error if the matched element isn't actually a select.\n * @param selector a CSS or directive selector\n * @returns the wrapped select, or null if no element was matched\n */\n select(selector: string | Type<any>): TestSelect | null {\n return this.querier.select(selector);\n }\n\n /**\n * Gets the first textarea matched by the given selector\n * @param selector a CSS or directive selector\n * @returns the wrapped textarea, or null if no element was matched. Throws an Error if the matched element isn't actually a textarea.\n * @throws {Error} if the matched element isn't actually a textarea\n */\n textarea(selector: string | Type<any>): TestTextArea | null {\n return this.querier.textarea(selector);\n }\n\n /**\n * Gets the first button matched by the given selector. Throws an Error if the matched element isn't actually a button.\n * @param selector a CSS or directive selector\n * @returns the wrapped button, or null if no element was matched\n */\n button(selector: string | Type<any>): TestButton | null {\n return this.querier.button(selector);\n }\n\n /**\n * Gets the first directive matching the given component directive selector and returns its component instance\n * @param selector the selector of a component directive\n */\n component<R>(selector: Type<R>): R {\n return this.querier.element(selector)?.debugElement?.componentInstance ?? null;\n }\n\n /**\n * Gets the directives matching the given component directive selector and returns their component instance\n * @param selector the selector of a component directive\n */\n components<R>(selector: Type<R>): Array<R> {\n return this.querier.elements(selector).map(e => e.debugElement.componentInstance);\n }\n\n /**\n * Gets the first element matching the given selector, then gets the given token from its injector, or null if there is no such token\n * @param selector a CSS or directive selector\n * @param token the token to get from the matched element injector\n */\n token<R>(selector: string | Type<any>, token: ProviderToken<R>): R | null {\n return this.querier.element(selector)?.debugElement?.injector?.get(token, null) ?? null;\n }\n\n /**\n * Gets the elements matching the given selector, then gets their given token from their injector, or null if there is no such token\n * @param selector a CSS or directive selector\n * @param token the token to get from the matched element injector\n */\n tokens<R>(selector: string | Type<any>, token: ProviderToken<R>): Array<R | null> {\n return this.querier.elements(selector).map(e => e.debugElement.injector.get(token, null) ?? null);\n }\n\n /**\n * Gets the element matching the given selector, and if found, creates and returns a custom TestElement of the provided\n * type. This is useful to create custom higher-level abstractions similar to TestInput, TestSelect, etc. for\n * custom elements or components.\n * @param selector a CSS or directive selector\n * @param customTestElementType the type of the TestElement subclass that will wrap the found element\n */\n custom<E extends TestElement>(selector: string | Type<any>, customTestElementType: Type<E>): E | null {\n const element = this.querier.element(selector);\n return element && new customTestElementType(this.tester, element.debugElement);\n }\n\n /**\n * Gets the elements matching the given selector, and creates and returns custom TestElements of the provided\n * type. This is useful to create custom higher-level abstractions similar to TestInput, TestSelect, etc. for\n * custom elements or components.\n * @param selector a CSS or directive selector\n * @param customTestElementType the type of the TestElement subclass that will wrap the found elements\n */\n customs<E extends TestElement>(selector: string | Type<any>, customTestElementType: Type<E>): Array<E> {\n return this.querier.elements(selector).map(element => new customTestElementType(this.tester, element.debugElement));\n }\n}\n","import { ComponentTester } from './component-tester';\nimport { TestElement } from './test-element';\nimport { DebugElement } from '@angular/core';\n\n/**\n * A wrapped DOM HTML element, providing additional methods and attributes helping with writing tests\n */\nexport class TestHtmlElement<E extends HTMLElement> extends TestElement<E> {\n constructor(tester: ComponentTester<unknown>, debugElement: DebugElement) {\n super(tester, debugElement);\n }\n\n /**\n * Clicks on the wrapped element, then triggers a change detection\n */\n click(): void {\n this.nativeElement.click();\n this.tester.detectChanges();\n }\n\n /**\n * Tests if the element is visible, in the same meaning (and implementation) as in jQuery, i.e.\n * present anywhere in the DOM, and visible.\n * An element is not visible typically, if its display style or any of its ancestors display style is none.\n */\n get visible(): boolean {\n return !!(this.nativeElement.offsetWidth || this.nativeElement.offsetHeight || this.nativeElement.getClientRects().length);\n }\n}\n","import { ComponentTester } from './component-tester';\nimport { TestHtmlElement } from './test-html-element';\nimport { DebugElement } from '@angular/core';\n\n/**\n * A wrapped button element, providing additional methods and attributes helping with writing tests\n */\nexport class TestButton extends TestHtmlElement<HTMLButtonElement> {\n constructor(tester: ComponentTester<unknown>, debugElement: DebugElement) {\n super(tester, debugElement);\n }\n\n /**\n * the disabled flag of the button\n */\n get disabled(): boolean {\n return this.nativeElement.disabled;\n }\n}\n","import { ComponentTester } from './component-tester';\nimport { TestHtmlElement } from './test-html-element';\nimport { DebugElement } from '@angular/core';\n\n/**\n * A wrapped DOM HTML select element, providing additional methods and attributes helping with writing tests\n */\nexport class TestSelect extends TestHtmlElement<HTMLSelectElement> {\n constructor(tester: ComponentTester<unknown>, debugElement: DebugElement) {\n super(tester, debugElement);\n }\n\n /**\n * Selects the option at the given index, then dispatches an event of type change and triggers a change detection\n */\n selectIndex(index: number): void {\n this.nativeElement.selectedIndex = index;\n this.dispatchEventOfType('change');\n }\n\n /**\n * Selects the first option with the given value, then dispatches an event of type change and triggers a change detection.\n * If there is no option with the given value, then does nothing\n * TODO should it throw instead?\n */\n selectValue(value: string): void {\n const index = this.optionValues.indexOf(value);\n if (index >= 0) {\n this.selectIndex(index);\n }\n }\n\n /**\n * Selects the first option with the given label (or text), then dispatches an event of type change and triggers a change detection.\n * If there is no option with the given label, then does nothing\n * TODO should it throw instead?\n */\n selectLabel(label: string): void {\n const index = this.optionLabels.indexOf(label);\n if (index >= 0) {\n this.selectIndex(index);\n }\n }\n\n /**\n * the selected index of the wrapped select\n */\n get selectedIndex(): number {\n return this.nativeElement.selectedIndex;\n }\n\n /**\n * the value of the selected option of the wrapped select, or null if there is no selected option\n */\n get selectedValue(): string | null {\n if (this.selectedIndex < 0) {\n return null;\n }\n return this.nativeElement.options[this.selectedIndex].value;\n }\n\n /**\n * the label (or text if no label) of the selected option of the wrapped select, or null if there is no selected option\n */\n get selectedLabel(): string | null {\n if (this.selectedIndex < 0) {\n return null;\n }\n return this.nativeElement.options[this.selectedIndex].label;\n }\n\n /**\n * the values of the options, as an array\n */\n get optionValues(): Array<string> {\n return (Array.prototype.slice.call(this.nativeElement.options) as Array<HTMLOptionElement>).map(option => option.value);\n }\n\n /**\n * the labels (or texts if no label) of the options, as an array\n */\n get optionLabels(): Array<string> {\n return (Array.prototype.slice.call(this.nativeElement.options) as Array<HTMLOptionElement>).map(option => option.label);\n }\n\n /**\n * the number of options in the select\n */\n get size(): number {\n return this.nativeElement.options.length;\n }\n\n /**\n * the disabled property of the wrapped select\n */\n get disabled(): boolean {\n return this.nativeElement.disabled;\n }\n}\n","import { ComponentTester } from './component-tester';\nimport { TestHtmlElement } from './test-html-element';\nimport { DebugElement } from '@angular/core';\n\n/**\n * A wrapped DOM HTML textarea element, providing additional methods and attributes helping with writing tests\n */\nexport class TestTextArea extends TestHtmlElement<HTMLTextAreaElement> {\n constructor(tester: ComponentTester<unknown>, debugElement: DebugElement) {\n super(tester, debugElement);\n }\n\n /**\n * Sets the value of the wrapped textarea, then dispatches an event of type input and triggers a change detection\n * @param value the new value of the textarea\n */\n fillWith(value: string): void {\n this.nativeElement.value = value;\n this.dispatchEventOfType('input');\n }\n\n /**\n * the value of the wrapped textarea\n */\n get value(): string {\n return this.nativeElement.value;\n }\n\n /**\n * the disabled property of the wrapped textarea\n */\n get disabled(): boolean {\n return this.nativeElement.disabled;\n }\n}\n","import { ComponentTester } from './component-tester';\nimport { TestHtmlElement } from './test-html-element';\nimport { DebugElement } from '@angular/core';\n\n/**\n * A wrapped DOM HTML input element, providing additional methods and attributes helping with writing tests\n */\nexport class TestInput extends TestHtmlElement<HTMLInputElement> {\n constructor(tester: ComponentTester<unknown>, debugElement: DebugElement) {\n super(tester, debugElement);\n }\n\n /**\n * Sets the value of the wrapped input, then dispatches an event of type input and triggers a change detection\n * @param value the new value of the input\n */\n fillWith(value: string): void {\n this.nativeElement.value = value;\n this.dispatchEventOfType('input');\n }\n\n /**\n * the value of the wrapped input\n */\n get value(): string {\n return this.nativeElement.value;\n }\n\n /**\n * the checked property of the wrapped input\n */\n get checked(): boolean {\n return this.nativeElement.checked;\n }\n\n /**\n * the disabled property of the wrapped input\n */\n get disabled(): boolean {\n return this.nativeElement.disabled;\n }\n\n /**\n * Checks the wrapped input, then dispatches an event of type change and triggers a change detection\n */\n check(): void {\n this.nativeElement.checked = true;\n this.dispatchEventOfType('change');\n }\n\n /**\n * Unchecks the wrapped input, then dispatches an event of type change and triggers a change detection\n */\n uncheck(): void {\n this.nativeElement.checked = false;\n this.dispatchEventOfType('change');\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { TestButton } from './test-button';\nimport { TestSelect } from './test-select';\nimport { TestElement } from './test-element';\nimport { TestTextArea } from './test-textarea';\nimport { TestInput } from './test-input';\nimport { TestHtmlElement } from './test-html-element';\nimport { ComponentTester } from './component-tester';\nimport { DebugElement, Type } from '@angular/core';\nimport { By } from '@angular/platform-browser';\n\n/**\n * @internal\n */\nexport class TestElementQuerier {\n constructor(private tester: ComponentTester<unknown>, private root: DebugElement) {}\n\n static wrap(childDebugElement: DebugElement, tester: ComponentTester<unknown>): TestElement {\n const childElement = childDebugElement.nativeElement;\n if (childElement instanceof HTMLButtonElement) {\n return new TestButton(tester, childDebugElement);\n } else if (childElement instanceof HTMLInputElement) {\n return new TestInput(tester, childDebugElement);\n } else if (childElement instanceof HTMLSelectElement) {\n return new TestSelect(tester, childDebugElement);\n } else if (childElement instanceof HTMLTextAreaElement) {\n return new TestTextArea(tester, childDebugElement);\n } else if (childElement instanceof HTMLElement) {\n return new TestHtmlElement(tester, childDebugElement);\n } else {\n return new TestElement(tester, childDebugElement);\n }\n }\n\n /**\n * Gets the first element matching the given selector and wraps it into a TestElement. The actual type\n * of the returned value is the TestElement subclass matching the type of the found element. So, if the\n * matched element is an input for example, the method will return a TestInput. You can thus use\n * `tester.element('#some-input') as TestInput`.\n * @param selector a CSS or directive selector\n * @returns the wrapped element, or null if no element matches the selector.\n */\n element(selector: string | Type<any>): TestElement | null {\n const childElement = this.query(selector);\n return childElement && TestElementQuerier.wrap(childElement, this.tester);\n }\n\n /**\n * Gets all the elements matching the given selector and wraps them into a TestElement. The actual type\n * of the returned elements is the TestElement subclass matching the type of the found element. So, if the\n * matched elements are inputs for example, the method will return an array of TestInput. You can thus use\n * `tester.elements('input') as Array<TestInput>`.\n * @param selector a CSS or directive selector\n * @returns the array of matched elements, empty if no element was matched\n */\n elements(selector: string | Type<any>): Array<TestElement> {\n const childElements = this.queryAll(selector);\n return childElements.map(debugElement => TestElementQuerier.wrap(debugElement, this.tester));\n }\n\n /**\n * Gets the first input matched by the given selector. Throws an Error if the matched element isn't actually an input.\n * @param selector a CSS or directive selector\n * @returns the wrapped input, or null if no element was matched\n */\n input(selector: string | Type<any>): TestInput | null {\n const childElement = this.query(selector);\n if (!childElement) {\n return null;\n } else if (!(childElement.nativeElement instanceof HTMLInputElement)) {\n throw new Error(`Element with selector ${selector} is not an HTMLInputElement`);\n }\n return new TestInput(this.tester, childElement);\n }\n\n /**\n * Gets the first select matched by the given selector. Throws an Error if the matched element isn't actually a select.\n * @param selector a CSS or directive selector\n * @returns the wrapped select, or null if no element was matched\n */\n select(selector: string | Type<any>): TestSelect | null {\n const childElement = this.query(selector);\n if (!childElement) {\n return null;\n } else if (!(childElement.nativeElement instanceof HTMLSelectElement)) {\n throw new Error(`Element with selector ${selector} is not an HTMLSelectElement`);\n }\n return new TestSelect(this.tester, childElement);\n }\n\n /**\n * Gets the first textarea matched by the given selector\n * @param selector a CSS or directive selector\n * @returns the wrapped textarea, or null if no element was matched. Throws an Error if the matched element isn't actually a textarea.\n * @throws {Error} if the matched element isn't actually a textarea\n */\n textarea(selector: string | Type<any>): TestTextArea | null {\n const childElement = this.query(selector);\n if (!childElement) {\n return null;\n } else if (!(childElement.nativeElement instanceof HTMLTextAreaElement)) {\n throw new Error(`Element with selector ${selector} is not an HTMLTextAreaElement`);\n }\n return new TestTextArea(this.tester, childElement);\n }\n\n /**\n * Gets the first button matched by the given selector. Throws an Error if the matched element isn't actually a button.\n * @param selector a CSS or directive selector\n * @returns the wrapped button, or null if no element was matched\n */\n button(selector: string | Type<any>): TestButton | null {\n const childElement = this.query(selector);\n if (!childElement) {\n return null;\n } else if (!(childElement.nativeElement instanceof HTMLButtonElement)) {\n throw new Error(`Element with selector ${selector} is not an HTMLButtonElement`);\n }\n return new TestButton(this.tester, childElement);\n }\n\n private query(selector: string | Type<any>): DebugElement | null {\n if (typeof selector === 'string') {\n return this.root.query(By.css(selector));\n } else {\n return this.root.query(By.directive(selector));\n }\n }\n\n private queryAll(selector: string | Type<any>): Array<DebugElement> {\n if (typeof selector === 'string') {\n return this.root.queryAll(By.css(selector));\n } else {\n return this.root.queryAll(By.directive(selector));\n }\n }\n}\n","/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { ComponentFixture, TestBed } from '@angular/core/testing';\nimport { DebugElement, ProviderToken, Type } from '@angular/core';\nimport { TestTextArea } from './test-textarea';\nimport { TestElement } from './test-element';\nimport { TestInput } from './test-input';\nimport { TestSelect } from './test-select';\nimport { TestButton } from './test-button';\nimport { TestElementQuerier } from './test-element-querier';\nimport { TestHtmlElement } from './test-html-element';\n\n/**\n * The main entry point of the API. It wraps an Angular ComponentFixture<T>, and gives access to its\n * most used properties and methods. It also allows getting elements wrapped in TestElement (and its subclasses)\n * @param <C> the type of the component to test\n */\nexport class ComponentTester<C> {\n /**\n * The test element of the component\n */\n readonly testElement: TestElement<HTMLElement>;\n\n /**\n * The component fixture of the component\n */\n readonly fixture: ComponentFixture<C>;\n\n /**\n * Creates a component fixture of the given type with the TestBed and wraps it into a ComponentTester\n */\n static create<C>(componentType: Type<C>): ComponentTester<C> {\n const fixture = TestBed.createComponent(componentType);\n return new ComponentTester(fixture);\n }\n\n /**\n * Creates a ComponentFixture for the given component type using the TestBed, and creates a ComponentTester\n * wrapping (and delegating) to this fixture. If a fixture is passed, then delegates to this fixture directly.\n *\n * Note that no `detectChanges()` call is made by this constructor. It's up to the subclass constructor,\n * or to the user of the created ComponentTester, to call `detectChanges()` at least once to trigger change\n * detection. This is necessary because some component templates can only be evaluated once inputs\n * have been set on the component instance.\n *\n * @param arg the type of the component to wrap, or a component fixture to wrap\n */\n constructor(arg: Type<C> | ComponentFixture<C>) {\n this.fixture = arg instanceof ComponentFixture ? arg : TestBed.createComponent(arg);\n this.testElement = TestElementQuerier.wrap(this.debugElement, this) as TestElement<HTMLElement>;\n }\n\n /**\n * The native DOM host element of the component\n */\n get nativeElement(): HTMLElement {\n return this.fixture.nativeElement;\n }\n\n /**\n * Gets the instance of the tested component from the wrapped fixture\n */\n get componentInstance(): C {\n return this.fixture.componentInstance;\n }\n\n /**\n * Gets the debug element from the wrapped fixture\n */\n get debugElement(): DebugElement {\n return this.fixture.debugElement;\n }\n\n /**\n * Gets the first element matching the given CSS selector and wraps it into a TestElement. The actual type\n * of the returned value is the TestElement subclass matching the type of the found element. So, if the\n * matched element is an input for example, the method will return a TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElement: TestHtmlElement&lt;HTMLDivElement> | null = tester.element('div');\n * </code>\n * @param selector a CSS selector\n * @returns the wrapped element, or null if no element matches the selector.\n */\n element<K extends keyof HTMLElementTagNameMap>(selector: K): TestHtmlElement<HTMLElementTagNameMap[K]> | null;\n /**\n * Gets the first element matching the given CSS selector and wraps it into a TestElement. The actual type\n * of the returned value is the TestElement subclass matching the type of the found element. So, if the\n * matched element is an input for example, the method will return a TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElement: TestElement&lt;SVGLineElement> | null = tester.element('line');\n * </code>\n * @param selector a CSS selector\n * @returns the wrapped element, or null if no element matches the selector.\n */\n element<K extends keyof SVGElementTagNameMap>(selector: K): TestElement<SVGElementTagNameMap[K]> | null;\n /**\n * Gets the first element matching the given CSS selector and wraps it into a TestElement. The actual type\n * of the returned value is the TestElement subclass matching the type of the found element. So, if the\n * matched element is an input for example, the method will return a TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElement: TestElement | null = tester.element('.selector');\n * </code>\n * @param selector a CSS or directive selector\n * @returns the wrapped element, or null if no element matches the selector.\n */\n element(selector: string | Type<any>): TestElement | null;\n /**\n * Gets the first element matching the given selector and wraps it into a TestElement. The actual type\n * of the returned value is the TestElement subclass matching the type of the found element. So, if the\n * matched element is an input for example, the method will return a TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElement: TestInput | null = tester.element&lt;HTMLInputElement>('.selector');\n * </code>\n * @param selector a CSS or directive selector\n * @returns the wrapped element, or null if no element matches the selector.\n */\n element<T extends HTMLInputElement>(selector: string | Type<any>): TestInput | null;\n /**\n * Gets the first element matching the given selector and wraps it into a TestElement. The actual type\n * of the returned value is the TestElement subclass matching the type of the found element. So, if the\n * matched element is an input for example, the method will return a TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElement: TestTextArea | null = tester.element&lt;HTMLTextAreaElement>('.selector');\n * </code>\n * @param selector a CSS or directive selector\n * @returns the wrapped element, or null if no element matches the selector.\n */\n element<T extends HTMLTextAreaElement>(selector: string | Type<any>): TestTextArea | null;\n /**\n * Gets the first element matching the given selector and wraps it into a TestElement. The actual type\n * of the returned value is the TestElement subclass matching the type of the found element. So, if the\n * matched element is an input for example, the method will return a TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElement: TestSelect | null = tester.element&lt;HTMLSelectElement>('.selector');\n * </code>\n * @param selector a CSS or directive selector\n * @returns the wrapped element, or null if no element matches the selector.\n */\n element<T extends HTMLSelectElement>(selector: string | Type<any>): TestSelect | null;\n /**\n * Gets the first element matching the given selector and wraps it into a TestElement. The actual type\n * of the returned value is the TestElement subclass matching the type of the found element. So, if the\n * matched element is an input for example, the method will return a TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElement: TestButton | null = tester.element&lt;HTMLButtonElement>('.selector');\n * </code>\n * @param selector a CSS or directive selector\n * @returns the wrapped element, or null if no element matches the selector.\n */\n element<T extends HTMLButtonElement>(selector: string | Type<any>): TestButton | null;\n /**\n * Gets the first element matching the given selector and wraps it into a TestElement. The actual type\n * of the returned value is the TestElement subclass matching the type of the found element. So, if the\n * matched element is an input for example, the method will return a TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElement: TestHtmlElement&lt;HTMLDivElement> | null = tester.element&lt;HTMLDivElement>('.selector');\n * </code>\n * @param selector a CSS or directive selector\n * @returns the wrapped element, or null if no element matches the selector.\n */\n element<T extends HTMLElement>(selector: string | Type<any>): TestHtmlElement<T> | null;\n /**\n * Gets the first element matching the given selector and wraps it into a TestElement. The actual type\n * of the returned value is the TestElement subclass matching the type of the found element. So, if the\n * matched element is an input for example, the method will return a TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElement: TestElement&lt;SVGLineElement> | null = tester.element&lt;SVGLineElement>('.selector');\n * </code>\n * @param selector a CSS or directive selector\n * @returns the wrapped element, or null if no element matches the selector.\n */\n element<T extends Element>(selector: string | Type<any>): TestElement<T> | null;\n element(selector: string | Type<any>): TestElement | null {\n return this.testElement.element(selector);\n }\n\n /**\n * Gets all the elements matching the given CSS selector and wraps them into a TestElement. The actual type\n * of the returned elements is the TestElement subclass matching the type of the found element. So, if the\n * matched elements are inputs for example, the method will return an array of TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElements: Array&lt;TestHtmlElement&lt;HTMLDivElement>> = tester.elements('div');\n * </code>\n * @param selector a CSS selector\n * @returns the array of matched elements, empty if no element was matched\n */\n elements<K extends keyof HTMLElementTagNameMap>(selector: K): Array<TestHtmlElement<HTMLElementTagNameMap[K]>>;\n /**\n * Gets all the elements matching the given CSS selector and wraps them into a TestElement. The actual type\n * of the returned elements is the TestElement subclass matching the type of the found element. So, if the\n * matched elements are inputs for example, the method will return an array of TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElements: Array&lt;TestElement&lt;SVGLineElement>> = tester.elements('line');\n * </code>\n * @param selector a CSS selector\n * @returns the array of matched elements, empty if no element was matched\n */\n elements<K extends keyof SVGElementTagNameMap>(selector: K): Array<TestElement<SVGElementTagNameMap[K]>>;\n /**\n * Gets all the elements matching the given selector and wraps them into a TestElement. The actual type\n * of the returned elements is the TestElement subclass matching the type of the found element. So, if the\n * matched elements are inputs for example, the method will return an array of TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElements: Array&lt;TestElement> = tester.elements('.selector');\n * </code>\n * @param selector a CSS or directive selector\n * @returns the array of matched elements, empty if no element was matched\n */\n elements(selector: string | Type<any>): Array<TestElement>;\n /**\n * Gets all the elements matching the given selector and wraps them into a TestElement. The actual type\n * of the returned elements is the TestElement subclass matching the type of the found element. So, if the\n * matched elements are inputs for example, the method will return an array of TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElements: Array&lt;TestInput> = tester.elements&lt;HTMLInputElement>('.selector');\n * </code>\n * @param selector a CSS or directive selector\n * @returns the array of matched elements, empty if no element was matched\n */\n elements<T extends HTMLInputElement>(selector: string | Type<any>): Array<TestInput>;\n /**\n * Gets all the elements matching the given selector and wraps them into a TestElement. The actual type\n * of the returned elements is the TestElement subclass matching the type of the found element. So, if the\n * matched elements are inputs for example, the method will return an array of TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElements: Array&lt;TestTextArea> = tester.elements&lt;HTMLTextAreaElement>('.selector');\n * </code>\n * @param selector a CSS or directive selector\n * @returns the array of matched elements, empty if no element was matched\n */\n elements<T extends HTMLTextAreaElement>(selector: string | Type<any>): Array<TestTextArea>;\n /**\n * Gets all the elements matching the given CSS selector and wraps them into a TestElement. The actual type\n * of the returned elements is the TestElement subclass matching the type of the found element. So, if the\n * matched elements are inputs for example, the method will return an array of TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElements: Array&lt;TestButton> = tester.elements&lt;HTMLButtonElement>('.selector');\n * </code>\n * @param selector a CSS or directive selector\n * @returns the array of matched elements, empty if no element was matched\n */\n elements<T extends HTMLButtonElement>(selector: string | Type<any>): Array<TestButton>;\n /**\n * Gets all the elements matching the given selector and wraps them into a TestElement. The actual type\n * of the returned elements is the TestElement subclass matching the type of the found element. So, if the\n * matched elements are inputs for example, the method will return an array of TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElements: Array&lt;TestSelect> = tester.elements<HTMLSelectElement>('.selector');\n * </code>\n * @param selector a CSS or directive selector\n * @returns the array of matched elements, empty if no element was matched\n */\n elements<T extends HTMLSelectElement>(selector: string | Type<any>): Array<TestSelect>;\n /**\n * Gets all the elements matching the given selector and wraps them into a TestElement. The actual type\n * of the returned elements is the TestElement subclass matching the type of the found element. So, if the\n * matched elements are inputs for example, the method will return an array of TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElements: Array&lt;TestHtmlElement&lt;HTMLDivElement>> = tester.elements&lt;HTMLDivElement>('.selector');\n * </code>\n * @param selector a CSS or directive selector\n * @returns the array of matched elements, empty if no element was matched\n */\n elements<T extends HTMLElement>(selector: string | Type<any>): Array<TestHtmlElement<T>>;\n /**\n * Gets all the elements matching the given selector and wraps them into a TestElement. The actual type\n * of the returned elements is the TestElement subclass matching the type of the found element. So, if the\n * matched elements are inputs for example, the method will return an array of TestInput.\n * <p>Usage:</p>\n * <code>\n * const testElements: Array&lt;TestElement&lt;SVGLineElement>> = tester.elements&lt;SVGLineElement>('.selector');\n * </code>\n * @param selector a CSS or directive selector\n * @returns the array of matched elements, empty if no element was matched\n */\n elements<T extends Element>(selector: string | Type<any>): Array<TestElement<T>>;\n elements(selector: string | Type<any>): Array<TestElement> {\n return this.testElement.elements(selector);\n }\n\n /**\n * Gets the first input matched by the given selector. Throws an Error if the matched element isn't actually an input.\n * @param selector a CSS or directive selector\n * @returns the wrapped input, or null if no element was matched\n */\n input(selector: string | Type<any>): TestInput | null {\n return this.testElement.input(selector);\n }\n\n /**\n * Gets the first select matched by the given selector. Throws an Error if the matched element isn't actually a select.\n * @param selector a CSS or directive selector\n * @returns the wrapped select, or null if no element was matched\n */\n select(selector: string | Type<any>): TestSelect | null {\n return this.testElement.select(selector);\n }\n\n /**\n * Gets the first textarea matched by the given selector\n * @param selector a CSS or directive selector\n * @returns the wrapped textarea, or null if no element was matched. Throws an Error if the matched element isn't actually a textarea.\n * @throws {Error} if the matched element isn't actually a textarea\n */\n textarea(selector: string | Type<any>): TestTextArea | null {\n return this.testElement.textarea(selector);\n }\n\n /**\n * Gets the first button matched by the given selector. Throws an Error if the matched element isn't actually a button.\n * @param selector a CSS or directive selector\n * @returns the wrapped button, or null if no element was matched\n */\n button(selector: string | Type<any>): TestButton | null {\n return this.testElement.button(selector);\n }\n\n /**\n * Gets the first directive matching the given component directive selector and returns its component instance\n * @param selector the selector of a component directive\n */\n component<R>(selector: Type<R>): R {\n return this.testElement.component(selector);\n }\n\n /**\n * Gets the directives matching the given component directive selector and returns their component instance\n * @param selector the selector of a component directive\n */\n components<R>(selector: Type<R>): Array<R> {\n return this.testElement.components(selector);\n }\n\n /**\n * Gets the first element matching the given selector, then gets the given token from its injector, or null if there is no such token\n * @param selector a CSS or directive selector\n * @param token the token to get from the matched element injector\n */\n token<R>(selector: string | Type<any>, token: ProviderToken<R>): R | null {\n return this.testElement.token(selector, token);\n }\n\n /**\n * Gets the elements matching the given selector, then gets their given token from their injector, or null if there is no such token\n * @param selector a CSS or directive selector\n * @param token the token to get from the matched element injector\n */\n tokens<R>(selector: string | Type<any>, token: ProviderToken<R>): Array<R | null> {\n return this.testElement.tokens(selector, token);\n }\n\n /**\n * Gets the element matching the given selector, and if found, creates and returns a custom TestElement of the provided\n * type. This is useful to create custom higher-level abstractions similar to TestInput, TestSelect, etc. for\n * custom elements or components.\n * @param selector a CSS or directive selector\n * @param customTestElementType the type of the TestElement subclass that will wrap the found element\n */\n custom<E extends TestElement>(selector: string | Type<any>, customTestElementType: Type<E>): E | null {\n return this.testElement.custom(selector, customTestElementType);\n }\n\n /**\n * Gets the elements matching the given selector, and creates and returns custom TestElements of the provided\n * type. This is useful to create custom higher-level abstractions similar to TestInput, TestSelect, etc. for\n * custom elements or components.\n * @param selector a CSS or directive selector\n * @param customTestElementType the type of the TestElement subclass that will wrap the found elements\n */\n customs<E extends TestElement>(selector: string | Type<any>, customTestElementType: Type<E>): Array<E> {\n return this.testElement.customs(selector, customTestElementType);\n }\n\n /**\n * Triggers a change detection using the wrapped fixture\n */\n detectChanges(checkNoChanges?: boolean): void {\n this.fixture.detectChanges(checkNoChanges);\n }\n}\n","import { ActivatedRoute, ActivatedRouteSnapshot, convertToParamMap, Data, Params, Route, UrlSegment } from '@angular/router';\nimport { BehaviorSubject, map, Observable } from 'rxjs';\nimport { Type } from '@angular/core';\n\n/**\n * Creates a fake partial ActivatedRoute for tests.\n *\n * If you pass params, then the created route's paramMap will contain the same values.\n * The same goes for queryParams and queryParamMap.\n *\n * If you pass a parent route and a snapshot, and the passed snapshot doesn't have a parent, then the snapshot's\n * parent will be set to the parent route snapshot. This allows the code under test to use\n * `route.parent.snapshot` or `route.snapshot.parent`.\n *\n * If you pass a snapshot with a parent, but don't pass a parent or pass a parent without snapshot, then the route's\n * parent snapshot will be set to the given snapshot's parent. This allows the code under test to use\n * `route.parent.snapshot` or `route.snapshot.parent`.\n *\n * @returns a partially populated, fake ActivatedRoute, depending on what you passed in\n * @deprecated favor stubRoute, which creates an easier to use and more logical stub\n */\nexport function fakeRoute(options: {\n url?: Observable<UrlSegment[]>;\n /** An observable of the matrix parameters scoped to this route */\n params?: Observable<Params>;\n /** An observable of the query parameters shared by all the routes */\n queryParams?: Observable<Params>;\n /** An observable of the URL fragment shared by all the routes */\n fragment?: Observable<string>;\n /** An observable of the static and resolved data of this route. */\n data?: Observable<Data>;\n /** The outlet name of the route. It's a constant */\n outlet?: string;\n /** The component of the route. It's a constant */\n component?: Type<unknown> | string | null;\n /** The current snapshot of this route */\n snapshot?: ActivatedRouteSnapshot;\n /** The configuration used to match this route */\n routeConfig?: Route | null;\n /** The root of the router state */\n root?: ActivatedRoute;\n /** The parent of this route in the router state tree */\n parent?: ActivatedRoute | null;\n /** The first child of this route in the router state tree */\n firstChild?: ActivatedRoute;\n /** The children of this route in the router state tree */\n children?: ActivatedRoute[];\n /** The path from the root of the router state tree to this route */\n pathFromRoot?: ActivatedRoute[];\n}): ActivatedRoute {\n const result = {\n url: options.url,\n params: options.params,\n paramMap: options.params && options.params.pipe(map(params => convertToParamMap(params))),\n queryParams: options.queryParams,\n queryParamMap: options.queryParams && options.queryParams.pipe(map(params => convertToParamMap(params))),\n fragment: options.fragment,\n data: options.data,\n outlet: options.outlet,\n component: options.component,\n snapshot: options.snapshot,\n routeConfig: options.routeConfig,\n root: options.root,\n parent: options.parent,\n firstChild: options.firstChild,\n children: options.children,\n pathFromRoot: options.pathFromRoot\n } as ActivatedRoute;\n\n for (let route: null | ActivatedRoute = result; route; route = route.parent) {\n if (route.parent && route.parent.snapshot && !route.snapshot) {\n // eslint-disable-next-line deprecation/deprecation\n route.snapshot = fakeSnapshot({});\n }\n if (route.parent && route.parent.snapshot && !route.snapshot.parent) {\n (route.snapshot as Omit<ActivatedRouteSnapshot, 'parent'> & { parent: ActivatedRouteSnapshot }).parent = route.parent.snapshot;\n }\n\n if (route.snapshot && route.snapshot.parent && !route.parent) {\n // eslint-disable-next-line deprecation/deprecation\n (route as Omit<ActivatedRoute, 'parent'> & { parent: ActivatedRoute }).parent = fakeRoute({});\n }\n if (route.snapshot && route.snapshot.parent && route.parent && !route.parent.snapshot) {\n route.parent.snapshot = route.snapshot.parent;\n }\n }\n\n return result;\n}\n\n/**\n * Creates a fake partial ActivatedRouteSnapshot for tests.\n *\n * If you pass params, then the created snapshot's paramMap will contain the same values.\n * The same goes for queryParams and queryParamMap.\n *\n * @returns a partially populated, fake ActivatedRoute, depending on what you passed in\n * @deprecated favor stubRoute, which creates an easier to use and more logical stub for both the route and its snapshot\n */\nexport function fakeSnapshot(options: {\n url?: UrlSegment[];\n /** The matrix parameters scoped to this route */\n params?: Params;\n /** The query parameters shared by all the routes */\n queryParams?: Params;\n /** The URL fragment shared by all the routes */\n fragment?: string;\n /** The static and resolved data of this route */\n data?: Data;\n /** The outlet name of the route */\n outlet?: string;\n /** The component of the route */\n component?: Type<unknown> | string | null;\n /** The configuration used to match this route */\n routeConfig?: Route;\n /** The root of the router state */\n root?: ActivatedRouteSnapshot;\n /** The parent of this route in the router state tree */\n parent?: ActivatedRouteSnapshot | null;\n /** The first child of this route in the router state tree */\n firstChild?: ActivatedRouteSnapshot | null;\n /** The children of this route in the router state tree */\n children?: ActivatedRouteSnapshot[];\n /** The path from the root of the router state tree to this route */\n pathFromRoot?: ActivatedRouteSnapshot[];\n}): ActivatedRouteSnapshot {\n return {\n url: options.url,\n params: options.params,\n paramMap: options.params && convertToParamMap(options.params),\n queryParams: options.queryParams,\n queryParamMap: options.queryParams && convertToParamMap(options.queryParams),\n fragment: options.fragment,\n data: options.data,\n outlet: options.outlet,\n component: options.component,\n routeConfig: options.routeConfig,\n root: options.root,\n parent: options.parent,\n firstChild: options.firstChild,\n children: options.children,\n pathFromRoot: options.pathFromRoot\n } as ActivatedRouteSnapshot;\n}\n\n/**\n * The options that are passed when creating an ActivatedRouteStub.\n */\nexport interface ActivatedRouteStubOptions {\n /**\n * The initial values of the parameters of the route\n */\n params?: Params;\n /**\n * The initial values of the query parameters of the route\n */\n queryParams?: Params;\n /**\n * The initial values of the data of the route\n */\n data?: Data;\n /**\n * The initial fragment of the route\n */\n fragment?: string | null;\n /**\n * The initial url of the route\n */\n url?: UrlSegment[];\n /**\n * The parent of the route\n */\n parent?: ActivatedRouteStub | null;\n /**\n * The first child of the route\n */\n firstChild?: ActivatedRouteStub | null;\n /**\n * The children of the route\n */\n children?: ActivatedRouteStub[] | null;\n /**\n * The configuration of the route\n */\n routeConfig?: Route | null;\n}\n\nclass ActivatedRouteSnapshotStub extends ActivatedRouteSnapshot {\n private _parent: ActivatedRouteSnapshot | null = null;\n private _root: ActivatedRouteSnapshot;\n private _firstChild: ActivatedRouteSnapshot | null = null;\n private _children: Array<ActivatedRouteSnapshot> = [];\n private _pathFromRoot: Array<ActivatedRouteSnapshot> = [];\n private _routeConfig: Route | null = null;\n\n get parent(): ActivatedRouteSnapshot | null {\n return this._parent;\n }\n\n set parent(value: ActivatedRouteSnapshot | null) {\n this._parent = value;\n }\n\n get root(): ActivatedRouteSnapshot {\n return this._root;\n }\n\n set root(value: ActivatedRouteSnapshot) {\n this._root = value;\n }\n\n get firstChild(): ActivatedRouteSnapshot | null {\n return this._firstChild;\n }\n\n set firstChild(value: ActivatedRouteSnapshot | null) {\n this._firstChild = value;\n }\n\n get children(): Array<ActivatedRouteSnapshot> {\n return this._children;\n }\n\n set children(value: Array<ActivatedRouteSnapshot>) {\n this._children = value;\n }\n\n get pathFromRoot(): Array<ActivatedRouteSnapshot> {\n return this._pathFromRoot;\n }\n\n set pathFromRoot(value: Array<ActivatedRouteSnapshot>) {\n this._pathFromRoot = value;\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n get routeConfig(): Route | null {\n return this._routeConfig;\n }\n\n set routeConfig(route: Route | null) {\n this._routeConfig = route;\n }\n\n constructor() {\n super();\n this._root = this;\n }\n}\n\n/**\n * A stub for ActivatedRoute. It behaves almost the same way as the actual ActivatedRoute, exposing a snapshot\n * and observables for the params, query params etc., which are kept in sync.\n *\n * In addition, this stub allows simulating a navigation by changing the params, the query params, the fragment, etc.\n * When that happens, the snapshot is modified, then the relevant observables emit the new values.\n *\n * There are some things that don't really work the same way as the real ActivatedRoute though:\n * - the handling of the firstChild and of the children is entirely under the tester's responsibility. Setting the parent\n * of a route stub does not add this route to the children of its parent, for example.\n * - when changing the params, query params, fragment, etc., their associated observable emits unconditionally, instead of\n * first checking if the value is actually different from before. It's thus the responsibility of the tester to not\n * change the values if they're the same as before.\n */\nexport class ActivatedRouteStub extends ActivatedRoute {\n private _firstChild: ActivatedRouteStub | null;\n private _children: Array<ActivatedRouteStub>;\n\n private readonly paramsSubject: BehaviorSubject<Params>;\n private readonly queryParamsSubject: BehaviorSubject<Params>;\n private readonly dataSubject: BehaviorSubject<Data>;\n private readonly fragmentSubject: BehaviorSubject<string | null>;\n private readonly urlSubject: BehaviorSubject<Array<UrlSegment>>;\n\n private _parent: ActivatedRouteStub | null;\n private _root: ActivatedRouteStub;\n private _pathFromRoot: Array<ActivatedRouteStub>;\n\n /**\n * Constructs a new instance, based on the given options.\n * If an option is not provided (or if no option is provided at all), then the route has a default value for this option\n * (empty parameters for example, null fragment, etc.)\n * If no parent is passed, then this route has no parent and is thus set as the root. Otherwise, the root and the path\n * from root are created based on the root and path from root of the given parent route.\n */\n constructor(options?: ActivatedRouteStubOptions) {\n super();\n\n const snapshot = new ActivatedRouteSnapshotStub();\n this.snapshot = snapshot;\n\n this._firstChild = options?.firstChild ?? null;\n this._children = options?.children ?? [];\n this._parent = options?.parent ?? null;\n this._root = this.parent?.root ?? this;\n this._pathFromRoot = this.parent ? [...this.parent.pathFromRoot, this] : [this];\n\n snapshot.params = options?.params ?? {};\n snapshot.queryParams = options?.queryParams ?? {};\n snapshot.data = options?.data ?? {};\n snapshot.fragment = options?.fragment ?? null;\n snapshot.url = options?.url ?? [];\n snapshot.routeConfig = options?.routeConfig ?? null;\n\n snapshot.firstChild = this.firstChild?.snapshot ?? null;\n snapshot.children = this.children?.map(route => route.snapshot) ?? [];\n snapshot.parent = this.parent?.snapshot ?? null;\n snapshot.root = this.root.snapshot;\n snapshot.pathFromRoot = this.pathFromRoot.map(route => route.snapshot);\n\n this.paramsSubject = new BehaviorSubject<Params>(this.snapshot.params);\n this.queryParamsSubject = new BehaviorSubject<Params>(this.snapshot.queryParams);\n this.dataSubject = new BehaviorSubject<Data>(this.snapshot.data);\n this.fragmentSubject = new BehaviorSubject<string | null>(this.snapshot.fragment);\n this.urlSubject = new BehaviorSubject<Array<UrlSegment>>(this.snapshot.url);\n\n this.params = this.paramsSubject.asObservable();\n this.queryParams = this.queryParamsSubject.asObservable();\n this.data = this.dataSubject.asObservable();\n this.fragment = this.fragmentSubject.asObservable();\n this.url = this.urlSubject.asObservable();\n }\n\n get root() {\n return this._root;\n }\n\n get parent(): ActivatedRouteStub | null {\n return this._parent;\n }\n\n get pathFromRoot(): Array<ActivatedRouteStub> {\n return this._pathFromRoot;\n }\n\n get firstChild(): ActivatedRouteStub | null {\n return this._firstChild;\n }\n\n get children(): Array<ActivatedRouteStub> {\n return this._children;\n }\n\n get routeConfig(): Route | null {\n return this.snapshot.routeConfig;\n }\n\n /**\n * Triggers a navigation with the given new parameters. All the other parts (query params etc.) stay as the are.\n * This is a shortcut to `triggerNavigation` that can be used to only change the parameters.\n */\n public setParams(params: Params): void {\n this.triggerNavigation({ params });\n }\n\n /**\n * Triggers a navigation with the given new parameter. The other parameters, as well as all the other parts (query params etc.)\n * stay as the are.\n * This is a shortcut to `triggerNavigation` that can be used to only change one parameter.\n */\n public setParam(name: string, value: string): void {\n this.setParams({ ...this.snapshot.params, [name]: value });\n }\n\n /**\n * Triggers a navigation with the given new query parameters. All the other parts (params etc.) stay as the are.\n * This is a shortcut to `triggerNavigation` that can be used to only change the query parameters.\n */\n public setQueryParams(queryParams: Params): void {\n this.triggerNavigation({ queryParams });\n }\n\n /**\n * Triggers a navigation with the given new parameter. The other query parameters, as well as all the other parts (params etc.)\n * stay as the are.\n * This is a shortcut to `triggerNavigation` that can be used to only change one query parameter.\n */\n public setQueryParam(name: string, value: string): void {\n this.setQueryParams({ ...this.snapshot.queryParams, [name]: value });\n }\n\n /**\n * Triggers a navigation with the given new data. The other parameters, as well as all the other parts (params etc.)\n * stay as the are.\n * This is a shortcut to `triggerNavigation` that can be used to only change the data.\n */\n public setData(data: Data): void {\n this.triggerNavigation({ data });\n }\n\n /**\n * Triggers a navigation with the given new data item. The other data, as well as all the other parts (params etc.)\n * stay as the are.\n * This is a shortcut to `triggerNavigation` that can be used to only change one data item.\n */\n public setDataItem(name: string, value: unknown): void {\n this.setData({ ...this.snapshot.data, [name]: value });\n }\n\n /**\n * Triggers a navigation with the given new fragment. The other parts (params etc.) stay as the are.\n * This is a shortcut to `triggerNavigation` that can be used to only change the fragment.\n */\n public setFragment(fragment: string | null): void {\n this.triggerNavigation({ fragment });\n }\n\n /**\n * Triggers a navigation with the given new url. The other parts (params etc.) stay as the are.\n * This is a shortcut to `triggerNavigation` that can be used to only change the url.\n */\n public setUrl(url: Array<UrlSegment>): void {\n this.triggerNavigation({ url });\n }\n\n /**\n * Triggers a navigation based on the given options. If an option is undefined or null, it's ignored. Except for fragment, which is only\n * ignored if it's undefined, because null is a valid value for a fragment.\n *\n * The non-ignored values are used to change the snapshot of the route. Once the snapshot has been modified,\n * the observables corresponding to the updated parts emit the new value.\n *\n * So, setting params and query params will make the params and queryParams observables emit, but not the fragment, data and\n * url observables for example. This is consistent to how the router behaves.\n */\n public triggerNavigation(options: {\n params?: Params;\n queryParams?: Params;\n fragment?: string | null;\n data?: Data | null;\n url?: Array<UrlSegment> | null;\n }): void {\n // set the snapshot first\n if (options.params) {\n this.snapshot.params = options.params;\n }\n if (options.queryParams) {\n this.snapshot.queryParams = options.queryParams;\n }\n if (options.fragment !== undefined) {\n this.snapshot.fragment = options.fragment;\n }\n if (options.data) {\n this.snapshot.data = options.data;\n }\n if (options.url) {\n this.snapshot.url = options.url;\n }\n\n // then emit everything that has changed\n if (options.params) {\n this.paramsSubject.next(this.snapshot.params);\n }\n if (options.queryParams) {\n this.queryParamsSubject.next(this.snapshot.queryParams);\n }\n if (options.fragment !== undefined) {\n this.fragmentSubject.next(this.snapshot.fragment);\n }\n if (options.data) {\n this.dataSubject.next(this.snapshot.data);\n }\n if (options.url) {\n this.urlSubject.next(this.snapshot.url);\n }\n }\n\n public toString(): string {\n return 'ActivatedRouteStub';\n }\n}\n\n/**\n * Creates a new ActivatedRouteStub, by calling its constructor.\n */\nexport function stubRoute(options?: ActivatedRouteStubOptions): ActivatedRouteStub {\n return new ActivatedRouteStub(options);\n}\n","import { TestTextArea } from './test-textarea';\nimport { TestInput } from './test-input';\nimport { TestElement } from './test-element';\nimport { TestSelect } from './test-select';\nimport { TestHtmlElement } from './test-html-element';\n\nconst speculoosMatchers: jasmine.CustomMatcherFactories = {\n /**\n * Checks that the receiver is a TestElement wrapping a DOM element and as the given CSS class\n */\n toHaveClass: (): jasmine.CustomMatcher => {\n const assert = (isNegative: boolean, el: unknown, expected: string) => {\n if (!el) {\n return { pass: false, message: `Expected to check class '${expected}' on element, but element was falsy` };\n }\n if (!(el instanceof TestElement)) {\n return { pass: false, message: `Expected to check class '${expected}' on element, but element was not a TestElement` };\n }\n const actual = el.classes;\n const pass = actual.indexOf(expected) !== -1;\n const message =\n `Expected element to ${isNegative ? 'not ' : ''}have class '${expected}', ` +\n `but had ${actual.length ? \"'\" + actual.join(', ') + \"'\" : 'none'}`;\n return { pass: isNegative ? !pass : pass, message };\n };\n return {\n compare: (el: unknown, expected: string): jasmine.CustomMatcherResult => {\n return assert(false, el, expected);\n },\n negativeCompare: (el: unknown, expected: string): jasmine.CustomMatcherResult => {\n return assert(true, el, expected);\n }\n };\n },\n\n /**\n * Checks that the receiver is a TestInput or a TestTextArea and has the given value\n */\n toHaveValue: (): jasmine.CustomMatcher => {\n const assert = (isNegative: boolean, el: unknown, expected: string) => {\n if (!el) {\n return { pass: false, message: `Expected to check value '${expected}' on element, but element was falsy` };\n }\n if (!(el instanceof TestInput) && !(el instanceof TestTextArea)) {\n return {\n pass: false,\n message: `Expected to check value '${expected}' on element, but element was neither a TestInput nor a TestTextArea`\n };\n }\n const actual = el.value;\n const pass = actual === expected;\n const message = `Expected element to ${isNegative ? 'not ' : ''}have value '${expected}', but had value '${actual}'`;\n return { pass: isNegative ? !pass : pass, message };\n };\n return {\n compare: (el: unknown, expected: string): jasmine.CustomMatcherResult => {\n return assert(false, el, expected);\n },\n negativeCompare: (el: unknown, expected: string): jasmine.CustomMatcherResult => {\n return assert(true, el, expected);\n }\n };\n },\n\n /**\n * Checks that the receiver is a TestElement wrapping a DOM element and has the exact given textContent\n */\n toHaveText: (): jasmine.CustomMatcher => {\n const assert = (isNegative: boolean, el: unknown, expected: string) => {\n if (!el) {\n return { pass: false, message: `Expected to check text '${expected}' on element, but element was falsy` };\n }\n if (!(el instanceof TestElement)) {\n return { pass: false, message: `Expected to check text '${expected}' on element, but element was not a TestElement` };\n }\n const actual = el.textContent;\n const pass = actual === expected;\n const message = `Expected element to ${isNegative ? 'not ' : ''}have text '${expected}', but had '${actual}'`;\n return { pass: isNegative ? !pass : pass, message };\n };\n return {\n compare: (el: unknown, expected: string): jasmine.CustomMatcherResult => {\n return assert(false, el, expected);\n },\n negativeCompare: (el: unknown, expected: string): jasmine.CustomMatcherResult => {\n return assert(true, el, expected);\n }\n };\n },\n\n /**\n * Checks that the receiver is a TestElement wrapping a DOM element and has the given textContent, after both have been trimmed.\n * So, An element such as\n * ```\n * <h1>\n * Some title\n * </h1>\n * ```\n * will pass the test\n * ```\n * expect(tester.title).toHaveTrimmedText('Some title')\n * ```\n */\n toHaveTrimmedText: (): jasmine.CustomMatcher => {\n const assert = (isNegative: boolean, el: unknown, expected: string) => {\n const trimmedExpected = expected.trim();\n if (!el) {\n return { pass: false, message: `Expected to check trimmed text '${trimmedExpected}' on element, but element was falsy` };\n }\n if (!(el instanceof TestElement)) {\n return {\n pass: false,\n message: `Expected to check trimmed text '${trimmedExpected}' on element, but element was not a TestElement`\n };\n }\n const actual = el.textContent?.trim();\n const pass = actual === trimmedExpected;\n const message = `Expected element to ${isNegative ? 'not ' : ''}have trimmed text '${trimmedExpected}', but had '${actual}'`;\n return { pass: isNegative ? !pass : pass, message };\n };\n return {\n compare: (el: unknown, expected: string): jasmine.CustomMatcherResult => {\n return assert(false, el, expected);\n },\n negativeCompare: (el: unknown, expected: string): jasmine.CustomMatcherResult => {\n return assert(true, el, expected);\n }\n };\n },\n\n /**\n * Checks that the receiver is a TestElement wrapping a DOM element and contains the given textContent\n */\n toContainText: (): jasmine.CustomMatcher => {\n const assert = (isNegative: boolean, el: unknown, expected: string) => {\n if (!el) {\n return { pass: false, message: `Expected to check text '${expected}' on element, but element was falsy` };\n }\n if (!(el instanceof TestElement)) {\n return { pass: false, message: `Expected to check text '${expected}' on element, but element was not a TestElement` };\n }\n const actual = el.textContent;\n if (!actual) {\n return {\n pass: isNegative,\n message: `Expected element to ${isNegative ? 'not ' : ''}contain text '${expected}', but had no text`\n };\n }\n const pass = actual.indexOf(expected) !== -1;\n const message = `Expected element to ${isNegative ? 'not ' : ''}contain text '${expected}', but had text '${actual}'`;\n return { pass: isNegative ? !pass : pass, message };\n };\n return {\n compare: (el: unknown, expected: string): jasmine.CustomMatcherResult => {\n return assert(false, el, expected);\n },\n negativeCompare: (el: unknown, expected: string): jasmine.CustomMatcherResult => {\n return assert(true, el, expected);\n }\n };\n },\n\n /**\n * Checks that the receiver is a TestElement wrapping a DOM element and contains the given textContent\n */\n toBeChecked: (): jasmine.CustomMatcher => {\n const assert = (isNegative: boolean, el: unknown) => {\n if (!el) {\n return { pass: false, message: `Expected to check if element was checked, but element was falsy` };\n }\n if (!(el instanceof TestInput)) {\n return { pass: false, message: `Expected to check if element was checked, but element was not a TestInput` };\n }\n const pass = el.checked;\n const message = `Expected element to be ${isNegative ? 'not ' : ''}checked, but was${!isNegative ? ' not' : ''}`;\n return { pass: isNegative ? !pass : pass, message };\n };\n return {\n compare: (el: unknown): jasmine.CustomMatcherResult => {\n return assert(false, el);\n },\n negativeCompare: (el: unknown): jasmine.CustomMatcherResult => {\n return assert(true, el);\n }\n };\n },\n\n /**\n * Checks that the receiver is a TestSelect wrapping a DOM element and has the given selected index\n */\n toHaveSelectedIndex: (): jasmine.CustomMatcher => {\n const assert = (isNegative: boolean, el: unknown, expected: number) => {\n if (!el) {\n return { pass: false, message: `Expected to check selected index ${expected} on element, but element was falsy` };\n }\n if (!(el instanceof TestSelect)) {\n return { pass: false, message: `Expected to check selected index ${expected} on element, but element was not a TestSelect` };\n }\n const actual = el.selectedIndex;\n const pass = actual === expected;\n const message = `Expected element to ${isNegative ? 'not ' : ''}have selected index ${expected}, but had ${actual}`;\n return { pass: isNegative ? !pass : pass, message };\n };\n return {\n compare: (el: unknown, expected: number): jasmine.CustomMatcherResult => {\n return assert(false, el, expected);\n },\n negativeCompare: (el: unknown, expected: number): jasmine.CustomMatcherResult => {\n return assert(true, el, expected);\n }\n };\n },\n\n /**\n * Checks that the receiver is a TestSelect wrapping a DOM element with the selected option's value equal to the given value\n */\n toHaveSelectedValue: (): jasmine.CustomMatcher => {\n const assert = (isNegative: boolean, el: unknown, expected: string) => {\n if (!el) {\n return { pass: false, message: `Expected to check selected value '${expected}' on element, but element was falsy` };\n }\n if (!(el instanceof TestSelect)) {\n return { pass: false, message: `Expected to check selected value '${expected}' on element, but element was not a TestSelect` };\n }\n const actual = el.selectedValue;\n const pass = actual === expected;\n const message = `Expected element to ${isNegative ? 'not ' : ''}have selected value '${expected}', but had '${actual}'`;\n return { pass: isNegative ? !pass : pass, message };\n };\n return {\n compare: (el: unknown, expected: string): jasmine.CustomMatcherResult => {\n return assert(false, el, expected);\n },\n negativeCompare: (el: unknown, expected: string): jasmine.CustomMatcherResult => {\n return assert(true, el, expected);\n }\n };\n },\n\n /**\n * Checks that the receiver is a TestSelect wrapping a DOM element with the selected option's label equal to the given label\n */\n toHaveSelectedLabel: (): jasmine.CustomMatcher => {\n const assert = (isNegative: boolean, el: unknown, expected: string) => {\n if (!el) {\n return { pass: false, message: `Expected to check selected label '${expected}' on element, but element was falsy` };\n }\n if (!(el instanceof TestSelect)) {\n return { pass: false, message: `Expected to check selected label '${expected}' on element, but element was not a TestSelect` };\n }\n const actual = el.selectedLabel;\n const pass = actual === expected;\n const message = `Expected element to ${isNegative ? 'not ' : ''}have selected label '${expected}', but had '${actual}'`;\n return { pass: isNegative ? !pass : pass, message };\n };\n return {\n compare: (el: unknown, expected: string): jasmine.CustomMatcherResult => {\n return assert(false, el, expected);\n },\n negativeCompare: (el: unknown, expected: string): jasmine.CustomMatcherResult => {\n return assert(true, el, expected);\n }\n };\n },\n\n /**\n * Checks that the receiver is a TestHtmlElement which is visible\n */\n toBeVisible: (): jasmine.CustomMatcher => {\n const assert = (isNegative: boolean, el: unknown) => {\n const expectedState = `${isNegative ? 'in' : ''}visible`;\n const inverseState = `${isNegative ? '' : 'in'}visible`;\n if (!el) {\n return { pass: false, message: `Expected to check if element was ${expectedState}, but element was falsy` };\n }\n if (!(el instanceof TestHtmlElement)) {\n return { pass: false, message: `Expected to check if element was ${expectedState}, but element was not a TestHtmlElement` };\n }\n const pass = el.visible;\n const message = `Expected element to be ${expectedState}, but was ${inverseState}`;\n return { pass: isNegative ? !pass : pass, message };\n };\n return {\n compare: (el: unknown): jasmine.CustomMatcherResult => {\n return assert(false, el);\n },\n negativeCompare: (el: unknown): jasmine.CustomMatcherResult => {\n return assert(true, el);\n }\n };\n }\n};\n\nexport { speculoosMatchers };\n","import { Type } from '@angular/core';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction collectMethodNames(proto: unknown): Array<string> {\n if (!proto || proto === Object.prototype) {\n return [];\n }\n const methodNames: Array<string> = [];\n for (const key of Object.getOwnPropertyNames(proto)) {\n const descriptor = Object.getOwnPropertyDescriptor(proto, key);\n if (descriptor && typeof descriptor.value === 'function' && key !== 'constructor') {\n methodNames.push(key);\n }\n }\n return [...methodNames, ...collectMethodNames(Object.getPrototypeOf(proto))];\n}\n\n/**\n * Creates a spy object for a class where all the methods of the class (and of its superclasses) are spies.\n * I.e., for a class `UserService` with methods `get()`, `create()`, `update()` and `delete()`, calling\n * `createMock(UserService)` is equivalent to calling\n * `jasmine.createSpyObj<UserService>('UserService', ['get', 'create', 'update', 'delete'])`.\n * @param type the type to mock (usually a service class)\n */\nexport function createMock<T>(type: Type<T>): jasmine.SpyObj<T> {\n return jasmine.createSpyObj<T>(type.name, collectMethodNames(type.prototype) as unknown as jasmine.SpyObjMethodNames<T>);\n}\n","/* eslint-disable */\n/*\n * Public API Surface of ngx-speculoos\n */\n/// <reference path=\"./jasmine-matchers.ts\" />\n\nexport * from './lib/component-tester';\nexport * from './lib/test-element';\nexport * from './lib/test-html-element';\nexport * from './lib/test-input';\nexport * from './lib/test-button';\nexport * from './lib/test-select';\nexport * from './lib/test-textarea';\nexport * from './lib/route';\nexport * from './lib/matchers';\nexport * from './lib/mock';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
@@ -12,6 +12,11 @@ declare namespace jasmine {
12
12
  * Checks that the receiver is a TestElement wrapping a DOM element and has the exact given textContent
13
13
  */
14
14
  toHaveText(textContent: string): boolean;
15
+ /**
16
+ * Checks that the receiver is a TestElement wrapping a DOM element and has the given textContent
17
+ * after both have been trimmed.
18
+ */
19
+ toHaveTrimmedText(textContent: string): boolean;
15
20
  /**
16
21
  * Checks that the receiver is a TestElement wrapping a DOM element and contains the given textContent
17
22
  */
@@ -1,5 +1,5 @@
1
1
  import { ComponentFixture } from '@angular/core/testing';
2
- import { DebugElement, Type } from '@angular/core';
2
+ import { DebugElement, ProviderToken, Type } from '@angular/core';
3
3
  import { TestTextArea } from './test-textarea';
4
4
  import { TestElement } from './test-element';
5
5
  import { TestInput } from './test-input';
@@ -80,82 +80,82 @@ export declare class ComponentTester<C> {
80
80
  * <code>
81
81
  * const testElement: TestElement | null = tester.element('.selector');
82
82
  * </code>
83
- * @param selector a CSS selector
83
+ * @param selector a CSS or directive selector
84
84
  * @returns the wrapped element, or null if no element matches the selector.
85
85
  */
86
- element(selector: string): TestElement | null;
86
+ element(selector: string | Type<any>): TestElement | null;
87
87
  /**
88
- * Gets the first element matching the given CSS selector and wraps it into a TestElement. The actual type
88
+ * Gets the first element matching the given selector and wraps it into a TestElement. The actual type
89
89
  * of the returned value is the TestElement subclass matching the type of the found element. So, if the
90
90
  * matched element is an input for example, the method will return a TestInput.
91
91
  * <p>Usage:</p>
92
92
  * <code>
93
93
  * const testElement: TestInput | null = tester.element&lt;HTMLInputElement>('.selector');
94
94
  * </code>
95
- * @param selector a CSS selector
95
+ * @param selector a CSS or directive selector
96
96
  * @returns the wrapped element, or null if no element matches the selector.
97
97
  */
98
- element<T extends HTMLInputElement>(selector: string): TestInput | null;
98
+ element<T extends HTMLInputElement>(selector: string | Type<any>): TestInput | null;
99
99
  /**
100
- * Gets the first element matching the given CSS selector and wraps it into a TestElement. The actual type
100
+ * Gets the first element matching the given selector and wraps it into a TestElement. The actual type
101
101
  * of the returned value is the TestElement subclass matching the type of the found element. So, if the
102
102
  * matched element is an input for example, the method will return a TestInput.
103
103
  * <p>Usage:</p>
104
104
  * <code>
105
105
  * const testElement: TestTextArea | null = tester.element&lt;HTMLTextAreaElement>('.selector');
106
106
  * </code>
107
- * @param selector a CSS selector
107
+ * @param selector a CSS or directive selector
108
108
  * @returns the wrapped element, or null if no element matches the selector.
109
109
  */
110
- element<T extends HTMLTextAreaElement>(selector: string): TestTextArea | null;
110
+ element<T extends HTMLTextAreaElement>(selector: string | Type<any>): TestTextArea | null;
111
111
  /**
112
- * Gets the first element matching the given CSS selector and wraps it into a TestElement. The actual type
112
+ * Gets the first element matching the given selector and wraps it into a TestElement. The actual type
113
113
  * of the returned value is the TestElement subclass matching the type of the found element. So, if the
114
114
  * matched element is an input for example, the method will return a TestInput.
115
115
  * <p>Usage:</p>
116
116
  * <code>
117
117
  * const testElement: TestSelect | null = tester.element&lt;HTMLSelectElement>('.selector');
118
118
  * </code>
119
- * @param selector a CSS selector
119
+ * @param selector a CSS or directive selector
120
120
  * @returns the wrapped element, or null if no element matches the selector.
121
121
  */
122
- element<T extends HTMLSelectElement>(selector: string): TestSelect | null;
122
+ element<T extends HTMLSelectElement>(selector: string | Type<any>): TestSelect | null;
123
123
  /**
124
- * Gets the first element matching the given CSS selector and wraps it into a TestElement. The actual type
124
+ * Gets the first element matching the given selector and wraps it into a TestElement. The actual type
125
125
  * of the returned value is the TestElement subclass matching the type of the found element. So, if the
126
126
  * matched element is an input for example, the method will return a TestInput.
127
127
  * <p>Usage:</p>
128
128
  * <code>
129
129
  * const testElement: TestButton | null = tester.element&lt;HTMLButtonElement>('.selector');
130
130
  * </code>
131
- * @param selector a CSS selector
131
+ * @param selector a CSS or directive selector
132
132
  * @returns the wrapped element, or null if no element matches the selector.
133
133
  */
134
- element<T extends HTMLButtonElement>(selector: string): TestButton | null;
134
+ element<T extends HTMLButtonElement>(selector: string | Type<any>): TestButton | null;
135
135
  /**
136
- * Gets the first element matching the given CSS selector and wraps it into a TestElement. The actual type
136
+ * Gets the first element matching the given selector and wraps it into a TestElement. The actual type
137
137
  * of the returned value is the TestElement subclass matching the type of the found element. So, if the
138
138
  * matched element is an input for example, the method will return a TestInput.
139
139
  * <p>Usage:</p>
140
140
  * <code>
141
141
  * const testElement: TestHtmlElement&lt;HTMLDivElement> | null = tester.element&lt;HTMLDivElement>('.selector');
142
142
  * </code>
143
- * @param selector a CSS selector
143
+ * @param selector a CSS or directive selector
144
144
  * @returns the wrapped element, or null if no element matches the selector.
145
145
  */
146
- element<T extends HTMLElement>(selector: string): TestHtmlElement<T> | null;
146
+ element<T extends HTMLElement>(selector: string | Type<any>): TestHtmlElement<T> | null;
147
147
  /**
148
- * Gets the first element matching the given CSS selector and wraps it into a TestElement. The actual type
148
+ * Gets the first element matching the given selector and wraps it into a TestElement. The actual type
149
149
  * of the returned value is the TestElement subclass matching the type of the found element. So, if the
150
150
  * matched element is an input for example, the method will return a TestInput.
151
151
  * <p>Usage:</p>
152
152
  * <code>
153
153
  * const testElement: TestElement&lt;SVGLineElement> | null = tester.element&lt;SVGLineElement>('.selector');
154
154
  * </code>
155
- * @param selector a CSS selector
155
+ * @param selector a CSS or directive selector
156
156
  * @returns the wrapped element, or null if no element matches the selector.
157
157
  */
158
- element<T extends Element>(selector: string): TestElement<T> | null;
158
+ element<T extends Element>(selector: string | Type<any>): TestElement<T> | null;
159
159
  /**
160
160
  * Gets all the elements matching the given CSS selector and wraps them into a TestElement. The actual type
161
161
  * of the returned elements is the TestElement subclass matching the type of the found element. So, if the
@@ -181,41 +181,41 @@ export declare class ComponentTester<C> {
181
181
  */
182
182
  elements<K extends keyof SVGElementTagNameMap>(selector: K): Array<TestElement<SVGElementTagNameMap[K]>>;
183
183
  /**
184
- * Gets all the elements matching the given CSS selector and wraps them into a TestElement. The actual type
184
+ * Gets all the elements matching the given selector and wraps them into a TestElement. The actual type
185
185
  * of the returned elements is the TestElement subclass matching the type of the found element. So, if the
186
186
  * matched elements are inputs for example, the method will return an array of TestInput.
187
187
  * <p>Usage:</p>
188
188
  * <code>
189
189
  * const testElements: Array&lt;TestElement> = tester.elements('.selector');
190
190
  * </code>
191
- * @param selector a CSS selector
191
+ * @param selector a CSS or directive selector
192
192
  * @returns the array of matched elements, empty if no element was matched
193
193
  */
194
- elements(selector: string): Array<TestElement>;
194
+ elements(selector: string | Type<any>): Array<TestElement>;
195
195
  /**
196
- * Gets all the elements matching the given CSS selector and wraps them into a TestElement. The actual type
196
+ * Gets all the elements matching the given selector and wraps them into a TestElement. The actual type
197
197
  * of the returned elements is the TestElement subclass matching the type of the found element. So, if the
198
198
  * matched elements are inputs for example, the method will return an array of TestInput.
199
199
  * <p>Usage:</p>
200
200
  * <code>
201
201
  * const testElements: Array&lt;TestInput> = tester.elements&lt;HTMLInputElement>('.selector');
202
202
  * </code>
203
- * @param selector a CSS selector
203
+ * @param selector a CSS or directive selector
204
204
  * @returns the array of matched elements, empty if no element was matched
205
205
  */
206
- elements<T extends HTMLInputElement>(selector: string): Array<TestInput>;
206
+ elements<T extends HTMLInputElement>(selector: string | Type<any>): Array<TestInput>;
207
207
  /**
208
- * Gets all the elements matching the given CSS selector and wraps them into a TestElement. The actual type
208
+ * Gets all the elements matching the given selector and wraps them into a TestElement. The actual type
209
209
  * of the returned elements is the TestElement subclass matching the type of the found element. So, if the
210
210
  * matched elements are inputs for example, the method will return an array of TestInput.
211
211
  * <p>Usage:</p>
212
212
  * <code>
213
213
  * const testElements: Array&lt;TestTextArea> = tester.elements&lt;HTMLTextAreaElement>('.selector');
214
214
  * </code>
215
- * @param selector a CSS selector
215
+ * @param selector a CSS or directive selector
216
216
  * @returns the array of matched elements, empty if no element was matched
217
217
  */
218
- elements<T extends HTMLTextAreaElement>(selector: string): Array<TestTextArea>;
218
+ elements<T extends HTMLTextAreaElement>(selector: string | Type<any>): Array<TestTextArea>;
219
219
  /**
220
220
  * Gets all the elements matching the given CSS selector and wraps them into a TestElement. The actual type
221
221
  * of the returned elements is the TestElement subclass matching the type of the found element. So, if the
@@ -224,71 +224,109 @@ export declare class ComponentTester<C> {
224
224
  * <code>
225
225
  * const testElements: Array&lt;TestButton> = tester.elements&lt;HTMLButtonElement>('.selector');
226
226
  * </code>
227
- * @param selector a CSS selector
227
+ * @param selector a CSS or directive selector
228
228
  * @returns the array of matched elements, empty if no element was matched
229
229
  */
230
- elements<T extends HTMLButtonElement>(selector: string): Array<TestButton>;
230
+ elements<T extends HTMLButtonElement>(selector: string | Type<any>): Array<TestButton>;
231
231
  /**
232
- * Gets all the elements matching the given CSS selector and wraps them into a TestElement. The actual type
232
+ * Gets all the elements matching the given selector and wraps them into a TestElement. The actual type
233
233
  * of the returned elements is the TestElement subclass matching the type of the found element. So, if the
234
234
  * matched elements are inputs for example, the method will return an array of TestInput.
235
235
  * <p>Usage:</p>
236
236
  * <code>
237
237
  * const testElements: Array&lt;TestSelect> = tester.elements<HTMLSelectElement>('.selector');
238
238
  * </code>
239
- * @param selector a CSS selector
239
+ * @param selector a CSS or directive selector
240
240
  * @returns the array of matched elements, empty if no element was matched
241
241
  */
242
- elements<T extends HTMLSelectElement>(selector: string): Array<TestSelect>;
242
+ elements<T extends HTMLSelectElement>(selector: string | Type<any>): Array<TestSelect>;
243
243
  /**
244
- * Gets all the elements matching the given CSS selector and wraps them into a TestElement. The actual type
244
+ * Gets all the elements matching the given selector and wraps them into a TestElement. The actual type
245
245
  * of the returned elements is the TestElement subclass matching the type of the found element. So, if the
246
246
  * matched elements are inputs for example, the method will return an array of TestInput.
247
247
  * <p>Usage:</p>
248
248
  * <code>
249
249
  * const testElements: Array&lt;TestHtmlElement&lt;HTMLDivElement>> = tester.elements&lt;HTMLDivElement>('.selector');
250
250
  * </code>
251
- * @param selector a CSS selector
251
+ * @param selector a CSS or directive selector
252
252
  * @returns the array of matched elements, empty if no element was matched
253
253
  */
254
- elements<T extends HTMLElement>(selector: string): Array<TestHtmlElement<T>>;
254
+ elements<T extends HTMLElement>(selector: string | Type<any>): Array<TestHtmlElement<T>>;
255
255
  /**
256
- * Gets all the elements matching the given CSS selector and wraps them into a TestElement. The actual type
256
+ * Gets all the elements matching the given selector and wraps them into a TestElement. The actual type
257
257
  * of the returned elements is the TestElement subclass matching the type of the found element. So, if the
258
258
  * matched elements are inputs for example, the method will return an array of TestInput.
259
259
  * <p>Usage:</p>
260
260
  * <code>
261
261
  * const testElements: Array&lt;TestElement&lt;SVGLineElement>> = tester.elements&lt;SVGLineElement>('.selector');
262
262
  * </code>
263
- * @param selector a CSS selector
263
+ * @param selector a CSS or directive selector
264
264
  * @returns the array of matched elements, empty if no element was matched
265
265
  */
266
- elements<T extends Element>(selector: string): Array<TestElement<T>>;
266
+ elements<T extends Element>(selector: string | Type<any>): Array<TestElement<T>>;
267
267
  /**
268
268
  * Gets the first input matched by the given selector. Throws an Error if the matched element isn't actually an input.
269
- * @param selector a CSS selector
269
+ * @param selector a CSS or directive selector
270
270
  * @returns the wrapped input, or null if no element was matched
271
271
  */
272
- input(selector: string): TestInput | null;
272
+ input(selector: string | Type<any>): TestInput | null;
273
273
  /**
274
274
  * Gets the first select matched by the given selector. Throws an Error if the matched element isn't actually a select.
275
- * @param selector a CSS selector
275
+ * @param selector a CSS or directive selector
276
276
  * @returns the wrapped select, or null if no element was matched
277
277
  */
278
- select(selector: string): TestSelect | null;
278
+ select(selector: string | Type<any>): TestSelect | null;
279
279
  /**
280
280
  * Gets the first textarea matched by the given selector
281
- * @param selector a CSS selector
281
+ * @param selector a CSS or directive selector
282
282
  * @returns the wrapped textarea, or null if no element was matched. Throws an Error if the matched element isn't actually a textarea.
283
283
  * @throws {Error} if the matched element isn't actually a textarea
284
284
  */
285
- textarea(selector: string): TestTextArea | null;
285
+ textarea(selector: string | Type<any>): TestTextArea | null;
286
286
  /**
287
287
  * Gets the first button matched by the given selector. Throws an Error if the matched element isn't actually a button.
288
- * @param selector a CSS selector
288
+ * @param selector a CSS or directive selector
289
289
  * @returns the wrapped button, or null if no element was matched
290
290
  */
291
- button(selector: string): TestButton | null;
291
+ button(selector: string | Type<any>): TestButton | null;
292
+ /**
293
+ * Gets the first directive matching the given component directive selector and returns its component instance
294
+ * @param selector the selector of a component directive
295
+ */
296
+ component<R>(selector: Type<R>): R;
297
+ /**
298
+ * Gets the directives matching the given component directive selector and returns their component instance
299
+ * @param selector the selector of a component directive
300
+ */
301
+ components<R>(selector: Type<R>): Array<R>;
302
+ /**
303
+ * Gets the first element matching the given selector, then gets the given token from its injector, or null if there is no such token
304
+ * @param selector a CSS or directive selector
305
+ * @param token the token to get from the matched element injector
306
+ */
307
+ token<R>(selector: string | Type<any>, token: ProviderToken<R>): R | null;
308
+ /**
309
+ * Gets the elements matching the given selector, then gets their given token from their injector, or null if there is no such token
310
+ * @param selector a CSS or directive selector
311
+ * @param token the token to get from the matched element injector
312
+ */
313
+ tokens<R>(selector: string | Type<any>, token: ProviderToken<R>): Array<R | null>;
314
+ /**
315
+ * Gets the element matching the given selector, and if found, creates and returns a custom TestElement of the provided
316
+ * type. This is useful to create custom higher-level abstractions similar to TestInput, TestSelect, etc. for
317
+ * custom elements or components.
318
+ * @param selector a CSS or directive selector
319
+ * @param customTestElementType the type of the TestElement subclass that will wrap the found element
320
+ */
321
+ custom<E extends TestElement>(selector: string | Type<any>, customTestElementType: Type<E>): E | null;
322
+ /**
323
+ * Gets the elements matching the given selector, and creates and returns custom TestElements of the provided
324
+ * type. This is useful to create custom higher-level abstractions similar to TestInput, TestSelect, etc. for
325
+ * custom elements or components.
326
+ * @param selector a CSS or directive selector
327
+ * @param customTestElementType the type of the TestElement subclass that will wrap the found elements
328
+ */
329
+ customs<E extends TestElement>(selector: string | Type<any>, customTestElementType: Type<E>): Array<E>;
292
330
  /**
293
331
  * Triggers a change detection using the wrapped fixture
294
332
  */
package/lib/mock.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ /// <reference types="@types/jasmine" />
2
+ import { Type } from '@angular/core';
3
+ /**
4
+ * Creates a spy object for a class where all the methods of the class (and of its superclasses) are spies.
5
+ * I.e., for a class `UserService` with methods `get()`, `create()`, `update()` and `delete()`, calling
6
+ * `createMock(UserService)` is equivalent to calling
7
+ * `jasmine.createSpyObj<UserService>('UserService', ['get', 'create', 'update', 'delete'])`.
8
+ * @param type the type to mock (usually a service class)
9
+ */
10
+ export declare function createMock<T>(type: Type<T>): jasmine.SpyObj<T>;