Skip to content

Commit

Permalink
Merge pull request #4 from cypress-io/optimize-unique-query
Browse files Browse the repository at this point in the history
fix: optimize unique query
  • Loading branch information
jennifer-shehane authored Dec 20, 2023
2 parents f1c8c1e + b8f2ae1 commit 249258f
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 24 deletions.
48 changes: 48 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Test

on: [push]

jobs:
test:
name: Test
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '20.x'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm run test

release:
name: Release
needs: test
runs-on: ubuntu-latest

permissions:
contents: write # to be able to publish a GitHub release
issues: write # to be able to comment on released issues
pull-requests: write # to be able to comment on released pull requests
id-token: write # to enable use of OIDC for npm provenance

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '20.x'
- name: Install dependencies
run: npm ci
- name: Release
if: github.ref == 'refs/heads/master'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: npx semantic-release
62 changes: 40 additions & 22 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,12 @@ function getAllSelectors( el, selectors, attributesToIgnore )
function testUniqueness( element, selector )
{
const { parentNode } = element;
const elements = parentNode.querySelectorAll( selector );
return elements.length === 1 && elements[ 0 ] === element;
try {
const elements = parentNode.querySelectorAll( selector );
return elements.length === 1 && elements[0] === element;
} catch (e) {
return false
}
}

/**
Expand Down Expand Up @@ -167,31 +171,45 @@ function getUniqueSelector( element, selectorTypes, attributesToIgnore )
* @api private
*/

export default function unique( el, options={} )
{
const { selectorTypes=['id', 'class', 'tag', 'nth-child'], attributesToIgnore= ['id', 'class', 'length'] } = options;
export default function unique( el, options={} ) {
const {
selectorTypes=['id', 'class', 'tag', 'nth-child'],
attributesToIgnore= ['id', 'class', 'length'],
selectorCache,
isUniqueCache
} = options;
const allSelectors = [];
const parents = getParents( el );

for( let elem of parents )
{
const selector = getUniqueSelector( elem, selectorTypes, attributesToIgnore );
if( Boolean( selector ) )
{
allSelectors.push( selector );
let currentElement = el
while (currentElement) {
let selector = selectorCache ? selectorCache.get(currentElement) : undefined

if (!selector) {
selector = getUniqueSelector(
currentElement,
selectorTypes,
attributesToIgnore
)
if (selectorCache) {
selectorCache.set(currentElement, selector)
}
}

allSelectors.unshift(selector)
const maybeUniqueSelector = allSelectors.join(' > ')
let isUniqueSelector = isUniqueCache ? isUniqueCache.get(maybeUniqueSelector) : undefined
if (isUniqueSelector === undefined) {
isUniqueSelector = isUnique(el, maybeUniqueSelector)
if (isUniqueCache) {
isUniqueCache.set(maybeUniqueSelector, isUniqueSelector)
}
}
}

const selectors = [];
for( let it of allSelectors )
{
selectors.unshift( it );
const selector = selectors.join( ' > ' );
if( isUnique( el, selector ) )
{
return selector;
if (isUniqueSelector) {
return maybeUniqueSelector
}
}
currentElement = currentElement.parentNode
}

return null;
}
8 changes: 6 additions & 2 deletions src/isUnique.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
export function isUnique( el, selector )
{
if( !Boolean( selector ) ) return false;
const elems = el.ownerDocument.querySelectorAll( selector );
return elems.length === 1 && elems[ 0 ] === el;
try {
var elems = el.ownerDocument.querySelectorAll(selector);
return elems.length === 1 && elems[0] === el;
} catch (e) {
return false
}
}

0 comments on commit 249258f

Please sign in to comment.