Software zum Installieren eines Smart-Mirror Frameworks , zum Nutzen von hochschulrelevanten Informationen, auf einem Raspberry-Pi.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

findStrategy.js 6.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. "use strict";
  2. var __importDefault = (this && this.__importDefault) || function (mod) {
  3. return (mod && mod.__esModule) ? mod : { "default": mod };
  4. };
  5. Object.defineProperty(exports, "__esModule", { value: true });
  6. exports.findStrategy = void 0;
  7. const fs_1 = __importDefault(require("fs"));
  8. const lodash_isplainobject_1 = __importDefault(require("lodash.isplainobject"));
  9. const constants_1 = require("../constants");
  10. const DEFAULT_STRATEGY = 'css selector';
  11. const DIRECT_SELECTOR_REGEXP = /^(id|css selector|xpath|link text|partial link text|name|tag name|class name|-android uiautomator|-android datamatcher|-android viewmatcher|-android viewtag|-ios uiautomation|-ios predicate string|-ios class chain|accessibility id):(.+)/;
  12. const XPATH_SELECTORS_START = [
  13. '/', '(', '../', './', '*/'
  14. ];
  15. const NAME_MOBILE_SELECTORS_START = [
  16. 'uia', 'xcuielementtype', 'android.widget', 'cyi'
  17. ];
  18. const XPATH_SELECTOR_REGEXP = [
  19. /^([a-z0-9|-]*)/,
  20. /(?:(\.|#)(-?[_a-zA-Z]+[_a-zA-Z0-9-]*))?/,
  21. /(?:\[(-?[_a-zA-Z]+[_a-zA-Z0-9-]*)(?:=(?:"|')([a-zA-z0-9\-_. ]+)(?:"|'))?\])?/,
  22. /(\*)?=(.+)$/,
  23. ];
  24. const IMAGEPATH_MOBILE_SELECTORS_ENDSWITH = [
  25. '.jpg', '.jpeg', '.gif', '.png', '.bmp', '.svg'
  26. ];
  27. const defineStrategy = function (selector) {
  28. if (lodash_isplainobject_1.default(selector)) {
  29. if (JSON.stringify(selector).indexOf('test.espresso.matcher.ViewMatchers') < 0)
  30. return '-android datamatcher';
  31. return '-android viewmatcher';
  32. }
  33. const stringSelector = selector;
  34. if (stringSelector.match(DIRECT_SELECTOR_REGEXP)) {
  35. return 'directly';
  36. }
  37. if (IMAGEPATH_MOBILE_SELECTORS_ENDSWITH.some(path => stringSelector.toLowerCase().endsWith(path))) {
  38. return '-image';
  39. }
  40. if (XPATH_SELECTORS_START.some(option => stringSelector.startsWith(option))) {
  41. return 'xpath';
  42. }
  43. if (stringSelector.startsWith('=')) {
  44. return 'link text';
  45. }
  46. if (stringSelector.startsWith('*=')) {
  47. return 'partial link text';
  48. }
  49. if (stringSelector.startsWith('id=')) {
  50. return 'id';
  51. }
  52. if (stringSelector.startsWith('android=')) {
  53. return '-android uiautomator';
  54. }
  55. if (stringSelector.startsWith('ios=')) {
  56. return '-ios uiautomation';
  57. }
  58. if (stringSelector.startsWith('~')) {
  59. return 'accessibility id';
  60. }
  61. if (NAME_MOBILE_SELECTORS_START.some(option => stringSelector.toLowerCase().startsWith(option))) {
  62. return 'class name';
  63. }
  64. if (stringSelector.search(/<[0-9a-zA-Z-]+( \/)*>/g) >= 0) {
  65. return 'tag name';
  66. }
  67. if (stringSelector.search(/^\[name=("|')([a-zA-z0-9\-_.@=[\] ']+)("|')]$/) >= 0) {
  68. return 'name';
  69. }
  70. if (selector === '..' || selector === '.') {
  71. return 'xpath';
  72. }
  73. if (stringSelector.match(new RegExp(XPATH_SELECTOR_REGEXP.map(rx => rx.source).join('')))) {
  74. return 'xpath extended';
  75. }
  76. };
  77. exports.findStrategy = function (selector, isW3C, isMobile) {
  78. const stringSelector = selector;
  79. let using = DEFAULT_STRATEGY;
  80. let value = selector;
  81. switch (defineStrategy(selector)) {
  82. case 'directly': {
  83. const match = stringSelector.match(DIRECT_SELECTOR_REGEXP);
  84. if (!match || !isMobile && isW3C && !constants_1.W3C_SELECTOR_STRATEGIES.includes(match[1])) {
  85. throw new Error('InvalidSelectorStrategy');
  86. }
  87. using = match[1];
  88. value = match[2];
  89. break;
  90. }
  91. case 'xpath': {
  92. using = 'xpath';
  93. break;
  94. }
  95. case 'id': {
  96. using = 'id';
  97. value = stringSelector.slice(3);
  98. break;
  99. }
  100. case 'link text': {
  101. using = 'link text';
  102. value = stringSelector.slice(1);
  103. break;
  104. }
  105. case 'partial link text': {
  106. using = 'partial link text';
  107. value = stringSelector.slice(2);
  108. break;
  109. }
  110. case '-android uiautomator': {
  111. using = '-android uiautomator';
  112. value = stringSelector.slice(8);
  113. break;
  114. }
  115. case '-android datamatcher': {
  116. using = '-android datamatcher';
  117. value = JSON.stringify(value);
  118. break;
  119. }
  120. case '-android viewmatcher': {
  121. using = '-android viewmatcher';
  122. value = JSON.stringify(value);
  123. break;
  124. }
  125. case '-ios uiautomation': {
  126. using = '-ios uiautomation';
  127. value = stringSelector.slice(4);
  128. break;
  129. }
  130. case 'accessibility id': {
  131. using = 'accessibility id';
  132. value = stringSelector.slice(1);
  133. break;
  134. }
  135. case 'class name': {
  136. using = 'class name';
  137. break;
  138. }
  139. case 'tag name': {
  140. using = 'tag name';
  141. value = stringSelector.replace(/<|>|\/|\s/g, '');
  142. break;
  143. }
  144. case 'name': {
  145. if (isMobile || !isW3C) {
  146. const match = stringSelector.match(/^\[name=("|')([a-zA-z0-9\-_.@=[\] ']+)("|')]$/);
  147. if (!match) {
  148. throw new Error(`InvalidSelectorMatch. Strategy 'name' has failed to match '${stringSelector}'`);
  149. }
  150. using = 'name';
  151. value = match[2];
  152. }
  153. break;
  154. }
  155. case 'xpath extended': {
  156. using = 'xpath';
  157. const match = stringSelector.match(new RegExp(XPATH_SELECTOR_REGEXP.map(rx => rx.source).join('')));
  158. if (!match) {
  159. throw new Error(`InvalidSelectorMatch: Strategy 'xpath extended' has failed to match '${stringSelector}'`);
  160. }
  161. const PREFIX_NAME = { '.': 'class', '#': 'id' };
  162. const conditions = [];
  163. const [tag, prefix, name, attrName, attrValue, partial, query] = match.slice(1);
  164. if (prefix) {
  165. conditions.push(`contains(@${PREFIX_NAME[prefix]}, "${name}")`);
  166. }
  167. if (attrName) {
  168. conditions.push(attrValue
  169. ? `contains(@${attrName}, "${attrValue}")`
  170. : `@${attrName}`);
  171. }
  172. conditions.push(partial ? `contains(., "${query}")` : `normalize-space() = "${query}"`);
  173. value = `.//${tag || '*'}[${conditions.join(' and ')}]`;
  174. break;
  175. }
  176. case '-image': {
  177. using = '-image';
  178. value = fs_1.default.readFileSync(stringSelector, { encoding: 'base64' });
  179. break;
  180. }
  181. }
  182. if (!isMobile && isW3C && !constants_1.W3C_SELECTOR_STRATEGIES.includes(using)) {
  183. throw new Error('InvalidSelectorStrategy');
  184. }
  185. return { using, value };
  186. };