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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  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.containsHeaderObject = exports.updateCapabilities = exports.getAutomationProtocol = exports.isStub = exports.enhanceElementsArray = exports.addLocatorStrategyHandler = exports.hasElementId = exports.getScrollPosition = exports.validateUrl = exports.assertDirectoryExists = exports.getAbsoluteFilepath = exports.getElementRect = exports.verifyArgsAndStripIfElement = exports.findElements = exports.findElement = exports.checkUnicode = exports.parseCSS = exports.transformToCharString = exports.getBrowserObject = exports.getElementFromResponse = exports.getPrototype = void 0;
  7. const fs_1 = __importDefault(require("fs"));
  8. const http_1 = __importDefault(require("http"));
  9. const path_1 = __importDefault(require("path"));
  10. const css_value_1 = __importDefault(require("css-value"));
  11. const rgb2hex_1 = __importDefault(require("rgb2hex"));
  12. const get_port_1 = __importDefault(require("get-port"));
  13. const grapheme_splitter_1 = __importDefault(require("grapheme-splitter"));
  14. const logger_1 = __importDefault(require("@wdio/logger"));
  15. const lodash_isobject_1 = __importDefault(require("lodash.isobject"));
  16. const lodash_isplainobject_1 = __importDefault(require("lodash.isplainobject"));
  17. const url_1 = require("url");
  18. const devtools_1 = require("devtools");
  19. const constants_1 = require("../constants");
  20. const findStrategy_1 = require("./findStrategy");
  21. const browserCommands = require('../commands/browser');
  22. const elementCommands = require('../commands/element');
  23. const log = logger_1.default('webdriverio');
  24. const INVALID_SELECTOR_ERROR = 'selector needs to be typeof `string` or `function`';
  25. const scopes = {
  26. browser: browserCommands,
  27. element: elementCommands
  28. };
  29. const applyScopePrototype = (prototype, scope) => {
  30. Object.entries(scopes[scope]).forEach(([commandName, command]) => {
  31. prototype[commandName] = { value: command };
  32. });
  33. };
  34. exports.getPrototype = (scope) => {
  35. const prototype = {
  36. puppeteer: { value: null, writable: true },
  37. _NOT_FIBER: { value: false, writable: true, configurable: true }
  38. };
  39. applyScopePrototype(prototype, scope);
  40. prototype.strategies = { value: new Map() };
  41. return prototype;
  42. };
  43. exports.getElementFromResponse = (res) => {
  44. if (!res) {
  45. return null;
  46. }
  47. if (res.ELEMENT) {
  48. return res.ELEMENT;
  49. }
  50. if (res[constants_1.ELEMENT_KEY]) {
  51. return res[constants_1.ELEMENT_KEY];
  52. }
  53. return null;
  54. };
  55. function getBrowserObject(elem) {
  56. const elemObject = elem;
  57. return elemObject.parent ? getBrowserObject(elemObject.parent) : elem;
  58. }
  59. exports.getBrowserObject = getBrowserObject;
  60. function transformToCharString(value, translateToUnicode = true) {
  61. const ret = [];
  62. if (!Array.isArray(value)) {
  63. value = [value];
  64. }
  65. for (const val of value) {
  66. if (typeof val === 'string') {
  67. translateToUnicode
  68. ? ret.push(...checkUnicode(val))
  69. : ret.push(...`${val}`.split(''));
  70. }
  71. else if (typeof val === 'number') {
  72. const entry = `${val}`.split('');
  73. ret.push(...entry);
  74. }
  75. else if (val && typeof val === 'object') {
  76. try {
  77. ret.push(...JSON.stringify(val).split(''));
  78. }
  79. catch (e) { }
  80. }
  81. else if (typeof val === 'boolean') {
  82. const entry = val ? 'true'.split('') : 'false'.split('');
  83. ret.push(...entry);
  84. }
  85. }
  86. return ret;
  87. }
  88. exports.transformToCharString = transformToCharString;
  89. function sanitizeCSS(value) {
  90. if (!value) {
  91. return value;
  92. }
  93. return value.trim().replace(/'/g, '').replace(/"/g, '').toLowerCase();
  94. }
  95. function parseCSS(cssPropertyValue, cssProperty) {
  96. var _a;
  97. const parsedValue = {
  98. property: cssProperty,
  99. value: cssPropertyValue.toLowerCase().trim(),
  100. parsed: {}
  101. };
  102. if (((_a = parsedValue.value) === null || _a === void 0 ? void 0 : _a.indexOf('rgb')) === 0) {
  103. parsedValue.value = parsedValue.value.replace(/\s/g, '');
  104. let color = parsedValue.value;
  105. parsedValue.parsed = rgb2hex_1.default(parsedValue.value);
  106. parsedValue.parsed.type = 'color';
  107. const colorType = /[rgba]+/g.exec(color) || [];
  108. parsedValue.parsed[colorType[0]] = color;
  109. }
  110. else if (parsedValue.property === 'font-family') {
  111. let font = css_value_1.default(cssPropertyValue);
  112. let string = parsedValue.value;
  113. let value = cssPropertyValue.split(/,/).map(sanitizeCSS);
  114. parsedValue.value = sanitizeCSS(font[0].value || font[0].string);
  115. parsedValue.parsed = { value, type: 'font', string };
  116. }
  117. else {
  118. try {
  119. const value = css_value_1.default(cssPropertyValue);
  120. if (value.length === 1) {
  121. parsedValue.parsed = value[0];
  122. }
  123. if (parsedValue.parsed.type && parsedValue.parsed.type === 'number' && parsedValue.parsed.unit === '') {
  124. parsedValue.value = parsedValue.parsed.value;
  125. }
  126. }
  127. catch (e) {
  128. }
  129. }
  130. return parsedValue;
  131. }
  132. exports.parseCSS = parseCSS;
  133. function checkUnicode(value, isDevTools = false) {
  134. return Object.prototype.hasOwnProperty.call(constants_1.UNICODE_CHARACTERS, value)
  135. ? isDevTools ? [value] : [constants_1.UNICODE_CHARACTERS[value]]
  136. : new grapheme_splitter_1.default().splitGraphemes(value);
  137. }
  138. exports.checkUnicode = checkUnicode;
  139. function fetchElementByJSFunction(selector, scope) {
  140. if (!scope.elementId) {
  141. return scope.execute(selector);
  142. }
  143. const script = (function (elem) {
  144. return selector.call(elem);
  145. }).toString().replace('selector', `(${selector.toString()})`);
  146. return getBrowserObject(scope).execute(`return (${script}).apply(null, arguments)`, scope);
  147. }
  148. async function findElement(selector) {
  149. if (typeof selector === 'string' || lodash_isplainobject_1.default(selector)) {
  150. const { using, value } = findStrategy_1.findStrategy(selector, this.isW3C, this.isMobile);
  151. return this.elementId
  152. ? this.findElementFromElement(this.elementId, using, value)
  153. : this.findElement(using, value);
  154. }
  155. if (typeof selector === 'function') {
  156. const notFoundError = new Error(`Function selector "${selector.toString()}" did not return an HTMLElement`);
  157. let elem = await fetchElementByJSFunction(selector, this);
  158. elem = Array.isArray(elem) ? elem[0] : elem;
  159. return exports.getElementFromResponse(elem) ? elem : notFoundError;
  160. }
  161. throw new Error(INVALID_SELECTOR_ERROR);
  162. }
  163. exports.findElement = findElement;
  164. async function findElements(selector) {
  165. if (typeof selector === 'string' || lodash_isplainobject_1.default(selector)) {
  166. const { using, value } = findStrategy_1.findStrategy(selector, this.isW3C, this.isMobile);
  167. return this.elementId
  168. ? this.findElementsFromElement(this.elementId, using, value)
  169. : this.findElements(using, value);
  170. }
  171. if (typeof selector === 'function') {
  172. const elems = await fetchElementByJSFunction(selector, this);
  173. const elemArray = Array.isArray(elems) ? elems : [elems];
  174. return elemArray.filter((elem) => elem && exports.getElementFromResponse(elem));
  175. }
  176. throw new Error(INVALID_SELECTOR_ERROR);
  177. }
  178. exports.findElements = findElements;
  179. function verifyArgsAndStripIfElement(args) {
  180. function verify(arg) {
  181. if (lodash_isobject_1.default(arg) && arg.constructor.name === 'Element') {
  182. const elem = arg;
  183. if (!elem.elementId) {
  184. throw new Error(`The element with selector "${elem.selector}" you trying to pass into the execute method wasn't found`);
  185. }
  186. return {
  187. [constants_1.ELEMENT_KEY]: elem.elementId,
  188. ELEMENT: elem.elementId
  189. };
  190. }
  191. return arg;
  192. }
  193. return !Array.isArray(args) ? verify(args) : args.map(verify);
  194. }
  195. exports.verifyArgsAndStripIfElement = verifyArgsAndStripIfElement;
  196. async function getElementRect(scope) {
  197. const rect = await scope.getElementRect(scope.elementId);
  198. let defaults = { x: 0, y: 0, width: 0, height: 0 };
  199. if (Object.keys(defaults).some((key) => rect[key] == null)) {
  200. const rectJs = await getBrowserObject(scope).execute(function (el) {
  201. if (!el || !el.getBoundingClientRect) {
  202. return;
  203. }
  204. const { left, top, width, height } = el.getBoundingClientRect();
  205. return {
  206. x: left + this.scrollX,
  207. y: top + this.scrollY,
  208. width,
  209. height
  210. };
  211. }, scope);
  212. Object.keys(defaults).forEach((key) => {
  213. if (rect[key] != null) {
  214. return;
  215. }
  216. if (rectJs && typeof rectJs[key] === 'number') {
  217. rect[key] = Math.floor(rectJs[key]);
  218. }
  219. else {
  220. log.error('getElementRect', { rect, rectJs, key });
  221. throw new Error('Failed to receive element rects via execute command');
  222. }
  223. });
  224. }
  225. return rect;
  226. }
  227. exports.getElementRect = getElementRect;
  228. function getAbsoluteFilepath(filepath) {
  229. return filepath.startsWith('/') || filepath.startsWith('\\') || filepath.match(/^[a-zA-Z]:\\/)
  230. ? filepath
  231. : path_1.default.join(process.cwd(), filepath);
  232. }
  233. exports.getAbsoluteFilepath = getAbsoluteFilepath;
  234. function assertDirectoryExists(filepath) {
  235. if (!fs_1.default.existsSync(path_1.default.dirname(filepath))) {
  236. throw new Error(`directory (${path_1.default.dirname(filepath)}) doesn't exist`);
  237. }
  238. }
  239. exports.assertDirectoryExists = assertDirectoryExists;
  240. function validateUrl(url, origError) {
  241. try {
  242. const urlObject = new url_1.URL(url);
  243. return urlObject.href;
  244. }
  245. catch (e) {
  246. if (origError) {
  247. throw origError;
  248. }
  249. return validateUrl(`http://${url}`, e);
  250. }
  251. }
  252. exports.validateUrl = validateUrl;
  253. function getScrollPosition(scope) {
  254. return getBrowserObject(scope)
  255. .execute(function () {
  256. return { scrollX: this.pageXOffset, scrollY: this.pageYOffset };
  257. });
  258. }
  259. exports.getScrollPosition = getScrollPosition;
  260. async function hasElementId(element) {
  261. if (!element.elementId) {
  262. const method = element.isReactElement ? 'react$' : '$';
  263. element.elementId = (await element.parent[method](element.selector)).elementId;
  264. }
  265. if (!element.elementId) {
  266. return false;
  267. }
  268. return true;
  269. }
  270. exports.hasElementId = hasElementId;
  271. function addLocatorStrategyHandler(scope) {
  272. return (name, script) => {
  273. if (scope.strategies.get(name)) {
  274. throw new Error(`Strategy ${name} already exists`);
  275. }
  276. scope.strategies.set(name, script);
  277. };
  278. }
  279. exports.addLocatorStrategyHandler = addLocatorStrategyHandler;
  280. exports.enhanceElementsArray = (elements, parent, selector, foundWith = '$$', props = []) => {
  281. elements.parent = parent;
  282. elements.selector = selector;
  283. elements.foundWith = foundWith;
  284. elements.props = props;
  285. return elements;
  286. };
  287. exports.isStub = (automationProtocol) => automationProtocol === './protocol-stub';
  288. exports.getAutomationProtocol = async (config) => {
  289. var _a;
  290. if (config.automationProtocol) {
  291. return config.automationProtocol;
  292. }
  293. if (config.hostname || config.port || config.path || (config.user && config.key)) {
  294. return 'webdriver';
  295. }
  296. if (config.capabilities &&
  297. typeof config.capabilities.browserName === 'string' &&
  298. !devtools_1.SUPPORTED_BROWSER.includes((_a = config.capabilities.browserName) === null || _a === void 0 ? void 0 : _a.toLowerCase())) {
  299. return 'webdriver';
  300. }
  301. if (config.capabilities && config.capabilities.alwaysMatch) {
  302. return 'webdriver';
  303. }
  304. const resp = await new Promise((resolve) => {
  305. const req = http_1.default.request(constants_1.DRIVER_DEFAULT_ENDPOINT, resolve);
  306. req.on('error', (error) => resolve({ error }));
  307. req.end();
  308. });
  309. const driverEndpointHeaders = resp;
  310. if (driverEndpointHeaders.req && driverEndpointHeaders.req.agent) {
  311. driverEndpointHeaders.req.agent.destroy();
  312. }
  313. if (driverEndpointHeaders && driverEndpointHeaders.statusCode === 200) {
  314. return 'webdriver';
  315. }
  316. return 'devtools';
  317. };
  318. exports.updateCapabilities = async (params, automationProtocol) => {
  319. const caps = params.capabilities;
  320. if (automationProtocol === 'webdriver' && caps.browserName === 'firefox') {
  321. if (!caps['moz:firefoxOptions']) {
  322. caps['moz:firefoxOptions'] = {};
  323. }
  324. if (!caps['moz:firefoxOptions'].args) {
  325. caps['moz:firefoxOptions'].args = [];
  326. }
  327. if (!caps['moz:firefoxOptions'].args.includes(constants_1.FF_REMOTE_DEBUG_ARG)) {
  328. caps['moz:firefoxOptions'].args.push(constants_1.FF_REMOTE_DEBUG_ARG, (await get_port_1.default()).toString());
  329. }
  330. }
  331. };
  332. exports.containsHeaderObject = (base, match) => {
  333. for (const [key, value] of Object.entries(match)) {
  334. if (typeof base[key] === 'undefined' || base[key] !== value) {
  335. return false;
  336. }
  337. }
  338. return true;
  339. };