Skip to content

Commit

Permalink
[7.x] [ftr/cheerio] improve cheerio types to include test subj… (#42541)
Browse files Browse the repository at this point in the history
  • Loading branch information
Spencer authored Aug 2, 2019
1 parent 92d318a commit 91b40d2
Show file tree
Hide file tree
Showing 4 changed files with 264 additions and 20 deletions.
7 changes: 2 additions & 5 deletions test/functional/services/apps_menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,9 @@ export function AppsMenuProvider({ getService }: FtrProviderContext) {
const appMenu = await testSubjects.find('navDrawer');
const $ = await appMenu.parseDomContent();

const links: Array<{
text: string;
href: string;
}> = $.findTestSubjects('navDrawerAppsMenuLink')
const links = $.findTestSubjects('navDrawerAppsMenuLink')
.toArray()
.map((link: any) => {
.map(link => {
return {
text: $(link).text(),
href: $(link).attr('href'),
Expand Down
16 changes: 6 additions & 10 deletions test/functional/services/doc_table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ export function DocTableProvider({ getService, getPageObjects }: FtrProviderCont
return await testSubjects.find('docTable');
}

public async getRowsText(): Promise<string[]> {
public async getRowsText() {
const table = await this.getTable();
const $ = await table.parseDomContent();
return $('[data-test-subj~="docTableRow"]')
return $.findTestSubjects('docTableRow')
.toArray()
.map((row: any) =>
$(row)
Expand Down Expand Up @@ -93,15 +93,11 @@ export function DocTableProvider({ getService, getPageObjects }: FtrProviderCont
return await detailsRow.findAllByCssSelector('[data-test-subj~="docTableRowAction"]');
}

public async getFields(
options: { isAnchorRow: boolean } = { isAnchorRow: false }
): Promise<string[][]> {
public async getFields(options: { isAnchorRow: boolean } = { isAnchorRow: false }) {
const table = await this.getTable();
const $ = await table.parseDomContent();
const rowLocator = options.isAnchorRow
? '[data-test-subj~="docTableAnchorRow"]'
: '[data-test-subj~="docTableRow"]';
const rows = $(rowLocator).toArray();
const rowLocator = options.isAnchorRow ? 'docTableAnchorRow' : 'docTableRow';
const rows = $.findTestSubjects(rowLocator).toArray();
const fields = rows.map((row: any) =>
$(row)
.find('[data-test-subj~="docTableField"]')
Expand All @@ -114,7 +110,7 @@ export function DocTableProvider({ getService, getPageObjects }: FtrProviderCont
public async getHeaderFields(): Promise<string[]> {
const table = await this.getTable();
const $ = await table.parseDomContent();
return $('[data-test-subj~="docTableHeaderField"]')
return $.findTestSubjects('docTableHeaderField')
.toArray()
.map((field: any) =>
$(field)
Expand Down
246 changes: 246 additions & 0 deletions test/functional/services/lib/web_element_wrapper/custom_cheerio_api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
/* eslint-disable */

/**
* Type interfaces extracted from node_modules/@types/cheerio/index.d.ts
* and customized to include our custom methods
*/

interface CheerioSelector {
(selector: string): CustomCheerio;
(selector: string, context: string): CustomCheerio;
(selector: string, context: CheerioElement): CustomCheerio;
(selector: string, context: CheerioElement[]): CustomCheerio;
(selector: string, context: Cheerio): CustomCheerio;
(selector: string, context: string, root: string): CustomCheerio;
(selector: string, context: CheerioElement, root: string): CustomCheerio;
(selector: string, context: CheerioElement[], root: string): CustomCheerio;
(selector: string, context: Cheerio, root: string): CustomCheerio;
(selector: any): CustomCheerio;
}

export interface CustomCheerioStatic extends CheerioSelector {
// Document References
// Cheerio https://github.com/cheeriojs/cheerio
// JQuery http://api.jquery.com
xml(): string;
root(): CustomCheerio;
contains(container: CheerioElement, contained: CheerioElement): boolean;
parseHTML(data: string, context?: Document, keepScripts?: boolean): Document[];

html(options?: CheerioOptionsInterface): string;
html(selector: string, options?: CheerioOptionsInterface): string;
html(element: CustomCheerio, options?: CheerioOptionsInterface): string;
html(element: CheerioElement, options?: CheerioOptionsInterface): string;

//
// CUSTOM METHODS
//
findTestSubjects(selector: string): CustomCheerio;
findTestSubject(selector: string): CustomCheerio;
}

export interface CustomCheerio {
// Document References
// Cheerio https://github.com/cheeriojs/cheerio
// JQuery http://api.jquery.com

[index: number]: CheerioElement;
length: number;

// Attributes

attr(): { [attr: string]: string };
attr(name: string): string;
attr(name: string, value: any): CustomCheerio;

data(): any;
data(name: string): any;
data(name: string, value: any): any;

val(): string;
val(value: string): CustomCheerio;

removeAttr(name: string): CustomCheerio;

has(selector: string): CustomCheerio;
has(element: CheerioElement): CustomCheerio;

hasClass(className: string): boolean;
addClass(classNames: string): CustomCheerio;

removeClass(): CustomCheerio;
removeClass(className: string): CustomCheerio;
removeClass(func: (index: number, className: string) => string): CustomCheerio;

toggleClass(className: string): CustomCheerio;
toggleClass(className: string, toggleSwitch: boolean): CustomCheerio;
toggleClass(toggleSwitch?: boolean): CustomCheerio;
toggleClass(
func: (index: number, className: string, toggleSwitch: boolean) => string,
toggleSwitch?: boolean
): CustomCheerio;

is(selector: string): boolean;
is(element: CheerioElement): boolean;
is(element: CheerioElement[]): boolean;
is(selection: CustomCheerio): boolean;
is(func: (index: number, element: CheerioElement) => boolean): boolean;

// Form
serialize(): string;
serializeArray(): Array<{ name: string; value: string }>;

// Traversing

find(selector: string): CustomCheerio;
find(element: CustomCheerio): CustomCheerio;

parent(selector?: string): CustomCheerio;
parents(selector?: string): CustomCheerio;
parentsUntil(selector?: string, filter?: string): CustomCheerio;
parentsUntil(element: CheerioElement, filter?: string): CustomCheerio;
parentsUntil(element: CustomCheerio, filter?: string): CustomCheerio;

prop(name: string): any;
prop(name: string, value: any): CustomCheerio;

closest(): CustomCheerio;
closest(selector: string): CustomCheerio;

next(selector?: string): CustomCheerio;
nextAll(): CustomCheerio;
nextAll(selector: string): CustomCheerio;

nextUntil(selector?: string, filter?: string): CustomCheerio;
nextUntil(element: CheerioElement, filter?: string): CustomCheerio;
nextUntil(element: CustomCheerio, filter?: string): CustomCheerio;

prev(selector?: string): CustomCheerio;
prevAll(): CustomCheerio;
prevAll(selector: string): CustomCheerio;

prevUntil(selector?: string, filter?: string): CustomCheerio;
prevUntil(element: CheerioElement, filter?: string): CustomCheerio;
prevUntil(element: CustomCheerio, filter?: string): CustomCheerio;

slice(start: number, end?: number): CustomCheerio;

siblings(selector?: string): CustomCheerio;

children(selector?: string): CustomCheerio;

contents(): CustomCheerio;

each(func: (index: number, element: CheerioElement) => any): CustomCheerio;
map(func: (index: number, element: CheerioElement) => any): CustomCheerio;

filter(selector: string): CustomCheerio;
filter(selection: CustomCheerio): CustomCheerio;
filter(element: CheerioElement): CustomCheerio;
filter(elements: CheerioElement[]): CustomCheerio;
filter(func: (index: number, element: CheerioElement) => boolean): CustomCheerio;

not(selector: string): CustomCheerio;
not(selection: CustomCheerio): CustomCheerio;
not(element: CheerioElement): CustomCheerio;
not(func: (index: number, element: CheerioElement) => boolean): CustomCheerio;

first(): CustomCheerio;
last(): CustomCheerio;

eq(index: number): CustomCheerio;

get(): any[];
get(index: number): any;

index(): number;
index(selector: string): number;
index(selection: CustomCheerio): number;

end(): CustomCheerio;

add(selectorOrHtml: string): CustomCheerio;
add(selector: string, context: Document): CustomCheerio;
add(element: CheerioElement): CustomCheerio;
add(elements: CheerioElement[]): CustomCheerio;
add(selection: CustomCheerio): CustomCheerio;

addBack(): CustomCheerio;
addBack(filter: string): CustomCheerio;

// Manipulation
appendTo(target: CustomCheerio): CustomCheerio;
prependTo(target: CustomCheerio): CustomCheerio;

append(content: string, ...contents: any[]): CustomCheerio;
append(content: Document, ...contents: any[]): CustomCheerio;
append(content: Document[], ...contents: any[]): CustomCheerio;
append(content: CustomCheerio, ...contents: any[]): CustomCheerio;

prepend(content: string, ...contents: any[]): CustomCheerio;
prepend(content: Document, ...contents: any[]): CustomCheerio;
prepend(content: Document[], ...contents: any[]): CustomCheerio;
prepend(content: CustomCheerio, ...contents: any[]): CustomCheerio;

after(content: string, ...contents: any[]): CustomCheerio;
after(content: Document, ...contents: any[]): CustomCheerio;
after(content: Document[], ...contents: any[]): CustomCheerio;
after(content: CustomCheerio, ...contents: any[]): CustomCheerio;

insertAfter(content: string): CustomCheerio;
insertAfter(content: Document): CustomCheerio;
insertAfter(content: CustomCheerio): CustomCheerio;

before(content: string, ...contents: any[]): CustomCheerio;
before(content: Document, ...contents: any[]): CustomCheerio;
before(content: Document[], ...contents: any[]): CustomCheerio;
before(content: CustomCheerio, ...contents: any[]): CustomCheerio;

insertBefore(content: string): CustomCheerio;
insertBefore(content: Document): CustomCheerio;
insertBefore(content: CustomCheerio): CustomCheerio;

remove(selector?: string): CustomCheerio;

replaceWith(content: string): CustomCheerio;
replaceWith(content: CheerioElement): CustomCheerio;
replaceWith(content: CheerioElement[]): CustomCheerio;
replaceWith(content: CustomCheerio): CustomCheerio;
replaceWith(content: () => CustomCheerio): CustomCheerio;

empty(): CustomCheerio;

html(): string | null;
html(html: string): CustomCheerio;

text(): string;
text(text: string): CustomCheerio;

wrap(content: string): CustomCheerio;
wrap(content: Document): CustomCheerio;
wrap(content: CustomCheerio): CustomCheerio;

css(propertyName: string): string;
css(propertyNames: string[]): string[];
css(propertyName: string, value: string): CustomCheerio;
css(propertyName: string, value: number): CustomCheerio;
css(propertyName: string, func: (index: number, value: string) => string): CustomCheerio;
css(propertyName: string, func: (index: number, value: string) => number): CustomCheerio;
css(properties: Record<string, any>): CustomCheerio;

// Rendering

// Miscellaneous

clone(): CustomCheerio;

// Not Documented

toArray(): CheerioElement[];

//
// CUSTOM METHODS
//
findTestSubjects(selector: string): CustomCheerio;
findTestSubject(selector: string): CustomCheerio;
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { PNG } from 'pngjs';
import cheerio from 'cheerio';
import testSubjSelector from '@kbn/test-subj-selector';
import { ToolingLog } from '@kbn/dev-utils';
import { CustomCheerio, CustomCheerioStatic } from './custom_cheerio_api';
// @ts-ignore not supported yet
import { scrollIntoViewIfNecessary } from './scroll_into_view_if_necessary';
import { Browsers } from '../../remote/browsers';
Expand Down Expand Up @@ -650,24 +651,28 @@ export class WebElementWrapper {
* Gets element innerHTML and wrap it up with cheerio
*
* @nonstandard
* @return {Promise<void>}
* @return {Promise<CustomCheerioStatic>}
*/
public async parseDomContent(): Promise<any> {
public async parseDomContent(): Promise<CustomCheerioStatic> {
const htmlContent: any = await this.getAttribute('innerHTML');
const $: any = cheerio.load(htmlContent, {
normalizeWhitespace: true,
xmlMode: true,
});

$.findTestSubjects = function testSubjects(selector: string) {
$.findTestSubjects = function findTestSubjects(this: CustomCheerioStatic, selector: string) {
return this(testSubjSelector(selector));
};

$.fn.findTestSubjects = function testSubjects(selector: string) {
$.fn.findTestSubjects = function findTestSubjects(this: CustomCheerio, selector: string) {
return this.find(testSubjSelector(selector));
};

$.findTestSubject = $.fn.findTestSubject = function testSubjects(selector: string) {
$.findTestSubject = function findTestSubject(this: CustomCheerioStatic, selector: string) {
return this.findTestSubjects(selector).first();
};

$.fn.findTestSubject = function findTestSubject(this: CustomCheerio, selector: string) {
return this.findTestSubjects(selector).first();
};

Expand Down

0 comments on commit 91b40d2

Please sign in to comment.