Skip to content

Commit

Permalink
better types
Browse files Browse the repository at this point in the history
  • Loading branch information
nichoth committed Sep 26, 2024
1 parent 1d4014d commit bab4a55
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 78 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
dist/*
public/*
test/*.js
docs
34 changes: 23 additions & 11 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,40 @@
"parser": "@typescript-eslint/parser",
"ignorePatterns": ["lib.es5.d.ts"],
"parserOptions": {
"requireConfigFile": false,
"babelOptions": {
}
"requireConfigFile": false
},
"extends": [
"standard",
"plugin:@typescript-eslint/recommended"
],
"plugins": [
"@typescript-eslint"
],
"rules": {
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-unused-vars": [
"error",
{
"argsIgnorePattern": "^_",
"varsIgnorePattern": "^_",
"caughtErrorsIgnorePattern": "^_"
}
],
"operator-linebreak": ["off"],
"react/jsx-first-prop-new-line": ["off"],
"react/jsx-indent-props": "off",
"react/jsx-closing-tag-location": ["off"],
"react/jsx-closing-bracket-location": ["off"],
"react/jsx-curly-newline": ["off"],
"react/jsx-boolean-value": ["off"],
"jsx-quotes": ["error", "prefer-double"],
"multiline-ternary": "off",
"@typescript-eslint/consistent-type-imports": [
"error",
{
"prefer": "type-imports"
}
],
"no-multiple-empty-lines": [
"error",
{
"max": 1,
"maxEOF": 1
}
],
"no-undef": "off",
"indent": ["error", 4, {
"SwitchCase": 1,
"ignoredNodes": ["TemplateLiteral *"]
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
[![types](https://img.shields.io/npm/types/msgpackr?style=flat-square)](README.md)
[![module](https://img.shields.io/badge/module-ESM%2FCJS-blue?style=flat-square)](README.md)
[![dependencies](https://img.shields.io/badge/dependencies-zero-brightgreen.svg?style=flat-square)](package.json)
[![semantic versioning](https://img.shields.io/badge/semver-2.0.0-blue?logo=semver&style=flat-square)](https://semver.org/)
[![license](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE)

Helpers for working with the DOM, useful for tests.
Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@
"build-cjs": "esbuild src/*.ts --format=cjs --tsconfig=tsconfig.build.json --keep-names --outdir=./dist --out-extension:.js=.cjs",
"build": "mkdir -p ./dist && rm -rf ./dist/* && npm run build-cjs && tsc --project tsconfig.build.json",
"build-docs": "typedoc ./src/index.ts",
"preversion": "npm run lint",
"changelog": "auto-changelog --template keepachangelog --breaking-pattern 'BREAKING CHANGE' && git add CHANGELOG.md && git commit -m 'changelog'",
"toc": "markdown-toc --maxdepth 3 -i README.md",
"preversion": "npm run lint",
"version": "npm run toc && auto-changelog -p --template keepachangelog --breaking-pattern 'BREAKING CHANGE:' && git add CHANGELOG.md README.md",
"postversion": "npm run changelog && git push --follow-tags && npm publish",
"prepublishOnly": "npm run build"
},
"dependencies": {},
"devDependencies": {
"@bicycle-codes/tapzero": "^0.10.0",
"@typescript-eslint/eslint-plugin": "^8.0.0",
Expand All @@ -30,6 +31,7 @@
"esbuild": "^0.24.0",
"eslint": "^8.57.0",
"eslint-config-standard": "^17.1.0",
"markdown-toc": "^1.2.0",
"tap-spec": "^5.0.0",
"tape-run": "^11.0.0",
"typedoc": "^0.26.2",
Expand Down
129 changes: 67 additions & 62 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,71 +131,74 @@ export function waitForText (args:{
multipleTags?:boolean,
regex?:RegExp
}):Promise<Element|null> {
return waitFor({
timeout: args.timeout
}, () => {
const {
element,
text,
regex,
multipleTags
} = args

const elems:Element[] = []

let maxLoop = 10000
const stack:Element[] = [element]
// Walk the DOM tree breadth first and build up a list of
// elements with the leafs last.
while (stack.length > 0 && maxLoop-- >= 0) {
const current = stack.pop()
if (current && current.children.length > 0) {
stack.push(...current.children)
elems.push(...current.children)
return waitFor(
{ timeout: args.timeout },
() => {
const {
element,
text,
regex,
multipleTags
} = args

const elems:Element[] = []

let maxLoop = 10000
const stack:Element[] = [element]
// Walk the DOM tree breadth first and build up a list of
// elements with the leafs last.
while (stack.length > 0 && maxLoop-- >= 0) {
const current = stack.pop()
if (current && current.children.length > 0) {
stack.push(...current.children)
elems.push(...current.children)
}
}
}

// Loop over children in reverse to scan the LEAF nodes first.
let match:HTMLElement|null = null
for (let i = elems.length - 1; i >= 0; i--) {
const node = elems[i]
if (!node.textContent) continue
// Loop over children in reverse to scan the LEAF nodes first.
let match:HTMLElement|null = null
for (let i = elems.length - 1; i >= 0; i--) {
const node = elems[i]
if (!node.textContent) continue

if (regex && regex.test(node.textContent)) {
return node
}
if (regex && regex.test(node.textContent)) {
return node
}

if (text && node.textContent?.includes(text)) {
return node
}
if (text && node.textContent?.includes(text)) {
return node
}

if (text && multipleTags) {
if (text[0] !== (node.textContent)[0]) continue

// if equal, check the sibling nodes
let sibling = node.nextSibling
let i = 1

// while there is a potential match, keep checking the siblings
while (i < text.length) {
if (sibling && (sibling.textContent === text[i])) {
// is equal still, check the next sibling
sibling = sibling.nextSibling
i++
match = node.parentElement
} else {
if (i === (text.length - 1)) return node.parentElement
match = null
break
if (text && multipleTags) {
if (text[0] !== (node.textContent)[0]) continue

// if equal, check the sibling nodes
let sibling = node.nextSibling
let i = 1

// while there is a potential match, keep checking the siblings
while (i < text.length) {
if (sibling && (sibling.textContent === text[i])) {
// is equal still, check the next sibling
sibling = sibling.nextSibling
i++
match = node.parentElement
} else {
if (i === (text.length - 1)) return node.parentElement
match = null
break
}
}
}
}
}

return match
})
return match
}
)
}

type Lambda = () => Element|null

/**
* Find an element
*
Expand All @@ -204,19 +207,21 @@ export function waitForText (args:{
* visible?: boolean, // the element needs to be visible
* timeout?: number // how long to wait
* }|string} args
* @param {() => HTMLElement | null} [lambda] [lambda]
* @param {() => Element|null} [lambda] A function to match an element
* @throws {Error} - Throws an error if neither `lambda` nor `selector`
* is provided.
* @throws {Error} - Throws an error if the element is not found within
* the timeout.
* @returns {HTMLElement|null} The HTML element
* @returns {Element|null} The HTML element
*/
export function waitFor <T extends (keyof HTMLElementTagNameMap)> (args:{
selector?:string,
visible?:boolean,
timeout?:number
// }|string, lambda?:() => Element|null):Promise<Element|null> {
}|string, lambda?:() => HTMLElement|null):Promise<ReturnType<typeof document.querySelector<T>>> {
export function waitFor (
args:{
selector?:string,
visible?:boolean,
timeout?:number
}|string,
lambda?:Lambda
):Promise<Element|null> {
let selector:string
let visible:boolean = true
let timeout = DEFAULT_TIMEOUT
Expand Down
6 changes: 3 additions & 3 deletions test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ test('call waitFor with a string', async t => {

test('dom.click', async t => {
const p = await dom.waitFor({ selector: 'p' })
dom.click(p!)
dom.click(p as HTMLElement)
t.ok('does not throw')
})

test('dom.waitForText', async t => {
Expand Down Expand Up @@ -204,8 +205,7 @@ test('another case for text + tags', async t => {

try {
const aaa = await dom.waitForText({
// @ts-ignore
element: document.getElementById('test-two'),
element: document.getElementById('test-two') as HTMLElement,
multipleTags: true,
text: 'aaa',
timeout: 1000
Expand Down

0 comments on commit bab4a55

Please sign in to comment.