fractal-page-object
Advanced tools
Comparing version 0.2.2 to 0.3.0
## v0.3.0 (2022-02-21) | ||
#### :rocket: Enhancement | ||
* `fractal-page-object` | ||
* [#49](https://github.com/bendemboski/fractal-page-object/pull/49) Support "scoped selectors" ([@bendemboski](https://github.com/bendemboski)) | ||
#### Committers: 1 | ||
- Ben Demboski ([@bendemboski](https://github.com/bendemboski)) | ||
## v0.2.2 (2022-02-03) | ||
@@ -3,0 +13,0 @@ |
import PageObject from '../page-object'; | ||
import type { PageObjectConstructor } from './types'; | ||
/** | ||
* Make a selector safe to pass to querySelector()/querySelectorAll(). We | ||
* construct selectors from fragments in each page object, we want to be able to | ||
* support a page object specifying things like `> .foo`, which isn't | ||
* technically a valid selector, i.e. will error if passed to | ||
* querySelector()/querySelectorAll(). So in order to ensure that we can | ||
* tolerate such selectors, we prepend `:scope `, which will be a no-op for | ||
* valid selectors, and will turn technically invalid but still sensical | ||
* selectors like `> .foo` into a valid selector. | ||
*/ | ||
export declare function safeSelector(selector: string): string; | ||
export declare function validateSelectorArguments<T extends PageObject>(selector: string, Class?: PageObjectConstructor<T>): void; |
@@ -60,3 +60,39 @@ var FractalPageObject = (function (exports) { | ||
function isPageObjectSubclass(Class) { | ||
return Class === PageObject || Class.prototype instanceof PageObject; | ||
} | ||
/** | ||
* Make a selector safe to pass to querySelector()/querySelectorAll(). We | ||
* construct selectors from fragments in each page object, we want to be able to | ||
* support a page object specifying things like `> .foo`, which isn't | ||
* technically a valid selector, i.e. will error if passed to | ||
* querySelector()/querySelectorAll(). So in order to ensure that we can | ||
* tolerate such selectors, we prepend `:scope `, which will be a no-op for | ||
* valid selectors, and will turn technically invalid but still sensical | ||
* selectors like `> .foo` into a valid selector. | ||
*/ | ||
function safeSelector(selector) { | ||
return `:scope ${selector}`; | ||
} | ||
function validateSelectorArguments(selector, Class) { | ||
if (!selector.trim()) { | ||
throw new Error('Cannot specify an empty selector'); | ||
} | ||
try { | ||
document.querySelector(selector); | ||
} | ||
catch (e) { | ||
try { | ||
document.querySelector(safeSelector(selector)); | ||
} | ||
catch (e) { | ||
throw new Error(`Selector is invalid: ${selector}`); | ||
} | ||
} | ||
if (Class && !isPageObjectSubclass(Class)) { | ||
throw new Error('Custom selector()/globalSelector() class must be PageObject or PageObject subclass'); | ||
} | ||
} | ||
/** | ||
* A class that represents a flexible selector, allowing intermediate indices. | ||
@@ -141,3 +177,3 @@ * It's an array of {@link SelectorFragment}s that represents a set of query and | ||
// Selector and index, so query all and index into result set | ||
el = el.querySelectorAll(selector)[index]; | ||
el = el.querySelectorAll(safeSelector(selector))[index]; | ||
} | ||
@@ -152,3 +188,3 @@ else { | ||
// Only a selector | ||
el = el.querySelector(selector); | ||
el = el.querySelector(safeSelector(selector)); | ||
} | ||
@@ -174,3 +210,3 @@ } | ||
// Selector and index, so query all and index into the result set | ||
el = matches[0].querySelectorAll(selector)[index]; | ||
el = matches[0].querySelectorAll(safeSelector(selector))[index]; | ||
} | ||
@@ -187,3 +223,3 @@ else { | ||
// Only a selector, so query for result set and covert to array | ||
matches = Array.from(matches[0].querySelectorAll(selector)); | ||
matches = Array.from(matches[0].querySelectorAll(safeSelector(selector))); | ||
} | ||
@@ -479,20 +515,2 @@ } | ||
function isPageObjectSubclass(Class) { | ||
return Class === PageObject || Class.prototype instanceof PageObject; | ||
} | ||
function validateSelectorArguments(selector, Class) { | ||
if (!selector) { | ||
throw new Error('Cannot specify an empty selector'); | ||
} | ||
try { | ||
document.querySelector(selector); | ||
} | ||
catch (e) { | ||
throw new Error(`Selector is invalid: ${selector}`); | ||
} | ||
if (Class && !isPageObjectSubclass(Class)) { | ||
throw new Error('Custom selector()/globalSelector() class must be PageObject or PageObject subclass'); | ||
} | ||
} | ||
/** | ||
@@ -499,0 +517,0 @@ * Define a child PageObject. It can optionally be supplied with a |
@@ -57,3 +57,39 @@ let root; | ||
function isPageObjectSubclass(Class) { | ||
return Class === PageObject || Class.prototype instanceof PageObject; | ||
} | ||
/** | ||
* Make a selector safe to pass to querySelector()/querySelectorAll(). We | ||
* construct selectors from fragments in each page object, we want to be able to | ||
* support a page object specifying things like `> .foo`, which isn't | ||
* technically a valid selector, i.e. will error if passed to | ||
* querySelector()/querySelectorAll(). So in order to ensure that we can | ||
* tolerate such selectors, we prepend `:scope `, which will be a no-op for | ||
* valid selectors, and will turn technically invalid but still sensical | ||
* selectors like `> .foo` into a valid selector. | ||
*/ | ||
function safeSelector(selector) { | ||
return `:scope ${selector}`; | ||
} | ||
function validateSelectorArguments(selector, Class) { | ||
if (!selector.trim()) { | ||
throw new Error('Cannot specify an empty selector'); | ||
} | ||
try { | ||
document.querySelector(selector); | ||
} | ||
catch (e) { | ||
try { | ||
document.querySelector(safeSelector(selector)); | ||
} | ||
catch (e) { | ||
throw new Error(`Selector is invalid: ${selector}`); | ||
} | ||
} | ||
if (Class && !isPageObjectSubclass(Class)) { | ||
throw new Error('Custom selector()/globalSelector() class must be PageObject or PageObject subclass'); | ||
} | ||
} | ||
/** | ||
* A class that represents a flexible selector, allowing intermediate indices. | ||
@@ -138,3 +174,3 @@ * It's an array of {@link SelectorFragment}s that represents a set of query and | ||
// Selector and index, so query all and index into result set | ||
el = el.querySelectorAll(selector)[index]; | ||
el = el.querySelectorAll(safeSelector(selector))[index]; | ||
} | ||
@@ -149,3 +185,3 @@ else { | ||
// Only a selector | ||
el = el.querySelector(selector); | ||
el = el.querySelector(safeSelector(selector)); | ||
} | ||
@@ -171,3 +207,3 @@ } | ||
// Selector and index, so query all and index into the result set | ||
el = matches[0].querySelectorAll(selector)[index]; | ||
el = matches[0].querySelectorAll(safeSelector(selector))[index]; | ||
} | ||
@@ -184,3 +220,3 @@ else { | ||
// Only a selector, so query for result set and covert to array | ||
matches = Array.from(matches[0].querySelectorAll(selector)); | ||
matches = Array.from(matches[0].querySelectorAll(safeSelector(selector))); | ||
} | ||
@@ -476,20 +512,2 @@ } | ||
function isPageObjectSubclass(Class) { | ||
return Class === PageObject || Class.prototype instanceof PageObject; | ||
} | ||
function validateSelectorArguments(selector, Class) { | ||
if (!selector) { | ||
throw new Error('Cannot specify an empty selector'); | ||
} | ||
try { | ||
document.querySelector(selector); | ||
} | ||
catch (e) { | ||
throw new Error(`Selector is invalid: ${selector}`); | ||
} | ||
if (Class && !isPageObjectSubclass(Class)) { | ||
throw new Error('Custom selector()/globalSelector() class must be PageObject or PageObject subclass'); | ||
} | ||
} | ||
/** | ||
@@ -496,0 +514,0 @@ * Define a child PageObject. It can optionally be supplied with a |
{ | ||
"name": "fractal-page-object", | ||
"version": "0.2.2", | ||
"version": "0.3.0", | ||
"description": "A lightweight page object implementation with a focus on simplicity and extensibility", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -0,1 +1,3 @@ | ||
import { safeSelector } from './helpers'; | ||
/** | ||
@@ -93,3 +95,3 @@ * An element of a {@link SelectorArray}, comprising a selector and optional | ||
// Selector and index, so query all and index into result set | ||
el = el.querySelectorAll(selector)[index]; | ||
el = el.querySelectorAll(safeSelector(selector))[index]; | ||
} else { | ||
@@ -102,3 +104,3 @@ // Only index, so index into the result set, which is just the current | ||
// Only a selector | ||
el = el.querySelector(selector); | ||
el = el.querySelector(safeSelector(selector)); | ||
} | ||
@@ -127,3 +129,3 @@ } | ||
// Selector and index, so query all and index into the result set | ||
el = matches[0].querySelectorAll(selector)[index]; | ||
el = matches[0].querySelectorAll(safeSelector(selector))[index]; | ||
} else { | ||
@@ -138,3 +140,5 @@ // Only index, so index into the result set, which is just the current | ||
// Only a selector, so query for result set and covert to array | ||
matches = Array.from(matches[0].querySelectorAll(selector)); | ||
matches = Array.from( | ||
matches[0].querySelectorAll(safeSelector(selector)) | ||
); | ||
} | ||
@@ -141,0 +145,0 @@ } |
@@ -10,2 +10,16 @@ import PageObject from '../page-object'; | ||
/** | ||
* Make a selector safe to pass to querySelector()/querySelectorAll(). We | ||
* construct selectors from fragments in each page object, we want to be able to | ||
* support a page object specifying things like `> .foo`, which isn't | ||
* technically a valid selector, i.e. will error if passed to | ||
* querySelector()/querySelectorAll(). So in order to ensure that we can | ||
* tolerate such selectors, we prepend `:scope `, which will be a no-op for | ||
* valid selectors, and will turn technically invalid but still sensical | ||
* selectors like `> .foo` into a valid selector. | ||
*/ | ||
export function safeSelector(selector: string): string { | ||
return `:scope ${selector}`; | ||
} | ||
export function validateSelectorArguments<T extends PageObject>( | ||
@@ -15,3 +29,3 @@ selector: string, | ||
): void { | ||
if (!selector) { | ||
if (!selector.trim()) { | ||
throw new Error('Cannot specify an empty selector'); | ||
@@ -23,3 +37,7 @@ } | ||
} catch (e) { | ||
throw new Error(`Selector is invalid: ${selector}`); | ||
try { | ||
document.querySelector(safeSelector(selector)); | ||
} catch (e) { | ||
throw new Error(`Selector is invalid: ${selector}`); | ||
} | ||
} | ||
@@ -26,0 +44,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
132907
2933