Created
June 26, 2018 05:49
-
-
Save Yuyz0112/a8ad3713171bb3ed8984c1104c747f10 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const lodash = require('lodash'); | |
const toArray = require('../utils/toArray'); | |
const { CONSTANTS: C } = require('../globals'); | |
const NAME_ALIAS = '名称'; | |
function hint(options) { | |
const rules = ['Check your selector value.']; | |
if (!options.debug) { | |
rules.push('Add { debug: true } to your options to get more info.'); | |
} | |
if (options.html) { | |
rules.push( | |
'MAKE SURE your selector values are Regexp because we are comparing it with innerHTML.' | |
); | |
} | |
const message = ` | |
There is no index got in this command. | |
If this was not expected, you can: | |
${rules.map((rule, index) => `${index + 1}. ${rule}`).join('\r\n')} | |
`; | |
console.log(message); | |
} | |
function check(record, selector) { | |
let passed = true; | |
for (let col in selector) { | |
if (!selector[col]) { | |
return; | |
} | |
let matched = false; | |
const matchers = toArray(selector[col]); | |
for (let matcher of matchers) { | |
const isString = lodash.isString(matcher); | |
const isRegExp = lodash.isRegExp(matcher); | |
if (!isString && !isRegExp) { | |
throw new Error(`Invalid matcher ${matcher}.`); | |
} | |
if (isString && matcher === record[col]) { | |
matched = true; | |
} | |
if (isRegExp && matcher.test(record[col])) { | |
matched = true; | |
} | |
} | |
if (!matched) { | |
passed = false; | |
} | |
} | |
return passed; | |
} | |
exports.command = function(selector, options = {}) { | |
// unify options | |
if (lodash.isFunction(options)) { | |
options = { | |
cb: options, | |
}; | |
} | |
const { | |
cb, // customize call back function | |
cssPrefix = '', // css prefix of the table | |
picker = 'first', // picker behavior | |
html, // collect innerHTML or innerText | |
keepSelector = false, // keep all selector in mock | |
debug, // log debug info | |
} = options; | |
// a wrapper of custom cb; | |
const _cb = function(error, indexes) { | |
if (debug) { | |
console.log('[debug]all indexes:', indexes); | |
console.log('[debug]picker:', picker); | |
} | |
switch (true) { | |
case !cb: | |
break; | |
case !!error: | |
cb(error); | |
break; | |
case indexes.length === 0: | |
case picker === 'all': | |
cb(null, indexes); | |
break; | |
case picker === 'first': | |
cb(null, [indexes[0]]); | |
break; | |
case picker === 'random': | |
cb(null, [indexes[lodash.random(indexes.length - 1)]]); | |
break; | |
case lodash.isFunction(picker): | |
cb(null, picker(indexes)); | |
break; | |
default: | |
cb(new Error(`Invalid picker ${picker}.`)); | |
} | |
// return a chainable client | |
return this.perform(() => {}); | |
}.bind(this); | |
// if selector is a number, just return it as the index; | |
if (lodash.isNumber(selector)) { | |
return _cb(null, [selector]); | |
} | |
// unify selector | |
switch (true) { | |
case lodash.isString(selector): | |
case lodash.isRegExp(selector): | |
selector = { [NAME_ALIAS]: selector }; | |
break; | |
case lodash.isArray(selector): | |
if (selector.every(lodash.isNumber)) { | |
return _cb(null, selector); | |
} | |
selector = { [NAME_ALIAS]: selector }; | |
break; | |
default: | |
} | |
if (!lodash.isPlainObject(selector)) { | |
return _cb(new Error('Failed to unify the selector.')); | |
} | |
// mock env will ignore name selector | |
if (C.IS_MOCK && selector[NAME_ALIAS] && !keepSelector) { | |
selector[NAME_ALIAS] = /.*/; | |
} | |
// use cssPrefix to determine which selectable table need to be used. | |
const headerCol = `${cssPrefix} .wizard-table-thead th`; | |
const row = `${cssPrefix} .wizard-table-row`; | |
if (debug) { | |
console.log('[debug]selector:', selector); | |
console.log('[debug]row:', row); | |
} | |
this.waitForElementVisible(row).execute( | |
function(headerCol, row, html) { | |
const cols = document.querySelectorAll(headerCol); | |
const colMap = {}; | |
for (let i = 0; i < cols.length; i++) { | |
colMap[i] = cols[i].innerText.trim(); | |
} | |
const rows = document.querySelectorAll(row); | |
const records = []; | |
// parse row dom to standard record | |
for (let i = 0; i < rows.length; i++) { | |
const tr = {}; | |
const tds = rows[i].querySelectorAll('td'); | |
for (let index = 0; index < tds.length; index++) { | |
tr[colMap[index]] = html ? tds[index].innerHTML.trim() : tds[index].innerText.trim(); | |
} | |
records.push(tr); | |
} | |
return records; | |
}, | |
[headerCol, row, html], | |
function(result) { | |
if (!result.value || result.value.length === 0) { | |
return _cb(new Error('No rows found.')); | |
} | |
if (debug) { | |
console.log('[debug]:table records:\r\n', result.value); | |
} | |
const indexes = []; | |
try { | |
for (let index = 0; index < result.value.length; index++) { | |
if (check(result.value[index], selector)) { | |
indexes.push(index); | |
} | |
} | |
} catch (error) { | |
return _cb(error); | |
} | |
if (!indexes.length) { | |
hint(options); | |
} | |
return _cb(null, indexes); | |
} | |
); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment