lib/page/finder_filter.js
class Private {
static stringEscape(str){
return str.split('\\"').map(s => s.replace(/"/g, '\\"')).join('\\"');
}
static haveContent(content, haveContent = true){
content = this.stringEscape(content.trim());
return `(elm, i)=>{ return elm.textContent && (elm.textContent.trim() == "${content}") === ${haveContent} }`;
}
static haveValue(value, haveValue = true){
value = this.stringEscape(value.trim());
return `(elm, i)=>{ return elm.value && (elm.value.trim() == "${value}") === ${haveValue} }`;
}
static haveClass(classname, haveClass = true){
return `(elm, i)=>{ return elm && (elm.classList.contains("${classname}")) === ${haveClass} }`;
}
static haveStyle(styleName, value, haveStyle = true){
return `(elm, i)=>{ let style = getComputeStyle(elm); return style && (style["${styleName}"] == "${value}") === ${haveStyle} }`
}
static haveAttribute(attrName, value, haveAttribute = true){
value = this.stringEscape(value.trim());
return `(elm, i)=>{ return (elm.getAttribute("${attrName}") == "${value}") === ${haveAttribute} }`;
}
static textMatch(regexp, textMatch = true){
return `(elm, i)=>{ return elm.textContent && (!!elm.textContent.match(${regexp.toString()})) === ${textMatch} }`;
}
static valueMatch(regexp, valueMatch = true){
return `(elm, i)=>{ return elm.value && (!!elm.value.match(${regexp.toString()})) === ${valueMatch} }`;
}
static textIncludes(content, textIncludes = true){
content = this.stringEscape(content.trim());
return `(elm, i)=>{ return elm.textContent && (!!elm.textContent.includes("${content}")) === ${textIncludes} }`;
}
static valueIncludes(value, valueIncludes = true){
value = this.stringEscape(value.trim());
return `(elm, i)=>{ return elm.value && (!!elm.value.includes("${value}")) === ${valueIncludes} }`;
}
static be(propName, bool){
return `(elm, i)=>{ return elm && elm.${propName} === ${bool} }`;
}
static isClickable(){
return "a,button,input[type=button],input[type=submit]";
}
static indexOf(index){
return `(elm, i)=>{ return i == ${index} }`;
}
static parent(){
return `(elm, i)=>{ return elm.parentNode }`;
}
static closest(selector){
selector = this.stringEscape(selector);
return `(elm, i)=>{ return elm.closest("${selector}") }`;
}
}
/**
* This class provides filtering methods for Finder.
* This class is Mixined to "Finder" class
*/
class FinderFilter {
/**
* @return {string} return function code to select elements which have given content as element.textContent
*/
static haveContent(content){
return Private.haveContent(content, true);
}
/**
* @return {string} return function code to select elements which do not have given content as element.textContent
*/
static notHaveContent(content){
return Private.haveContent(content, false);
}
/**
* Alias of haveContent
* @return {string} return function code to select elements which have given content as element.textContent
*/
static haveText(text){
return this.haveContent(text)
}
/**
* Alias of notHaveContent
* @return {string} return function code to select elements which do not have given content as element.textContent
*/
static notHaveText(text){
return this.notHaveContent(text)
}
/**
* @return {string} return function code to select elements which have given value as element.value
*/
static haveValue(value){
return Private.haveValue(value, true);
}
/**
* @return {string} return function code to select elements which do not have given value as element.value
*/
static notHaveValue(value){
return Private.haveValue(value, false);
}
/**
* @return {string} return function code to select elements which have given value as element.checked attribute.
*/
static beChecked(bool){
return Private.be("checked", bool)
}
/**
* @return {string} return function code to select elements which have given value as element.selected attribute.
*/
static beSelected(bool){
return Private.be("selected", bool)
}
/**
* @return {string} return function code to select elements which have given value as element.disabled attribute.
*/
static beDisabled(bool){
return Private.be("disabled", bool)
}
/**
* @return {string} return function code to select elements which have given value in element.classList attribute.
*/
static haveClass(classname){
return Private.haveClass(classname, true);
}
/**
* @return {string} return function code to select elements which do not have given value in element.classList attribute.
*/
static notHaveClass(classname){
return Private.haveClass(classname, false);
}
/**
* @return {string} return function code to select elements which have given value in window.getComputedStyle(element)
*/
static haveStyle(styleName, value){
return Private.haveStyle(styleName, value, true);
}
/**
* @return {string} return function code to select elements which do not have given value in window.getComputedStyle(element)
*/
static notHaveStyle(styleName, value){
return Private.haveStyle(styleName, value, false);
}
/**
* @return {string} return function code to select elements which have given value in element.getAttribute(attrName)
*/
static haveAttribute(attrName, value){
return Private.haveAttribute(attrName, value, true);
}
/**
* @return {string} return function code to select elements which do not have given value in element.getAttribute(attrName)
*/
static notHaveAttribute(attrName, value){
return Private.haveAttribute(attrName, value, false);
}
/**
* @return {string} return function code to select elements which match given regexp as element.textContent
*/
static textMatch(regexp){
if (!(regexp instanceof RegExp)) {
regexp = new RegExp(regexp);
}
return Private.textMatch(regexp, true);
}
/**
* @return {string} return function code to select elements which match given regexp as element.value
*/
static valueMatch(regexp){
if (!(regexp instanceof RegExp)) {
regexp = new RegExp(regexp);
}
return Private.valueMatch(regexp, true);
}
/**
* @return {string} return function code to select elements which includes given content as element.textContent
*/
static textIncludes(content){
return Private.textIncludes(content, true);
}
/**
* @return {string} return function code to select elements which includes given value as element.value
*/
static valueIncludes(value){
return Private.valueIncludes(value, true);
}
/**
* @return {string} return css selector string to select clickable elements like a, button, input[type=button]
*/
static isClickable(){
return Private.isClickable()
}
/**
* @return {string} return function code to select elements which is in given index in elements
*/
static indexOf(i){
return Private.indexOf(i);
}
/**
* @return {string} return function code to map parent node.
*/
static parent(){
return Private.parent();
}
/**
* @return {string} return function code to map closest node which matches given selector.
*/
static closest(selector){
return Private.closest(selector);
}
////// instance methods /////////////////////////////////////////////////////////////////////
/**
* @return {Finder} return filtered Finder object which have the specified value
*/
haveValue(val){
return this.find(FinderFilter.haveValue(val))
}
/**
* @return {Finder} return filtered Finder object which does not have the specified value
*/
notHaveValue(val){
return this.find(FinderFilter.notHaveValue(val))
}
/**
* @return {Finder} return filtered Finder object which have the specified text
*/
haveContent(content){
return this.find(FinderFilter.haveContent(content))
}
/**
* @return {Finder} return filtered Finder object which does not have the specified text
*/
notHaveContent(content){
return this.find(FinderFilter.notHaveContent(content))
}
/**
* @return {Finder} return filtered Finder object which have the specified text
*/
haveText(text){
return this.find(FinderFilter.haveContent(text))
}
/**
* @return {Finder} return filtered Finder object which does not have the specified text
*/
notHaveText(text){
return this.find(FinderFilter.notHaveContent(text))
}
/**
* @return {Finder} return filtered Finder object which have been checked
*/
beChecked(){
return this.find(FinderFilter.beChecked(true))
}
/**
* @return {Finder} return filtered Finder object which do not have been checked
*/
notBeChecked(){
return this.find(FinderFilter.beChecked(false))
}
/**
* @return {Finder} return filtered Finder object which have been selected
*/
beSelected(){
return this.find(FinderFilter.beSelected(true))
}
/**
* @return {Finder} return filtered Finder object which do not have been selected
*/
notBeSelected(){
return this.find(FinderFilter.beSelected(false))
}
/**
* @return {Finder} return filtered Finder object which have specified CssClass
*/
haveCssClass(classname){
return this.find(FinderFilter.haveClass(classname))
}
/**
* @return {Finder} return filtered Finder object which do not have specified CssClass
*/
notHaveCssClass(classname){
return this.find(FinderFilter.notHaveClass(classname))
}
/**
* @return {Finder} return filtered Finder object which have specified CssProperty
*/
haveCssProperty(propName, value){
return this.find(FinderFilter.haveStyle(propName, value))
}
/**
* @return {Finder} return filtered Finder object which do not have specified CssProperty
*/
notHaveCssProperty(propName, value){
return this.find(FinderFilter.notHaveStyle(propName, value))
}
/**
* @return {Finder} return filtered Finder object which have specified attribute-value
*/
haveAttribute(attrName, value){
return this.find(FinderFilter.haveAttribute(attrName, value))
}
/**
* @return {Finder} return filtered Finder object which do not have specified attribute-value
*/
notHaveAttribute(attrName, value){
return this.find(FinderFilter.notHaveAttribute(attrName, value))
}
/**
* @return {Finder} return filtered Finder object whose textContent matches given regexp
*/
textMatch(regexp){
return this.find(FinderFilter.textMatch(regexp))
}
/**
* @return {Finder} return filtered Finder object whose value matches given regexp
*/
valueMatch(regexp){
return this.find(FinderFilter.valueMatch(regexp))
}
/**
* @return {Finder} return filtered Finder object whose textContent includes given content
*/
textIncludes(content){
return this.find(FinderFilter.textIncludes(content))
}
/**
* @return {Finder} return filtered Finder object whose value includes given value
*/
valueIncludes(value){
return this.find(FinderFilter.valueIncludes(value))
}
/**
* @return {Finder} return filtered Finder object which is clickable like a, button, input[type=button]
*/
isClickable(){
return this.find(FinderFilter.isClickable())
}
/**
* @return {Finder} return filtered Finder object which is in given index in elements
*/
indexOf(i){
return this.find(FinderFilter.indexOf(i));
}
/**
* @return {Finder} return Finder for the first matched element. this is same to "indexOf(0)"
*/
first(){
return this.indexOf(0);
}
/**
* @return {Finder} return Finder object for the parent element.
*/
parent(){
return this.map(FinderFilter.parent())
}
/**
* @return {Finder} return Finder object for the closest node.
*/
closest(selector){
return this.map(FinderFilter.closest(selector))
}
}
module.exports = FinderFilter;