handleTestCondition.js 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import { nanoid } from 'nanoid';
  2. import FindElement from '@/utils/FindElement';
  3. import { automaRefDataStr } from './utils';
  4. function handleConditionElement({ data, type }) {
  5. const selectorType = data.selector.startsWith('/') ? 'xpath' : 'cssSelector';
  6. const element = FindElement[selectorType](data);
  7. const { 1: actionType } = type.split('#');
  8. if (!element) {
  9. if (actionType === 'visible' || actionType === 'invisible') return false;
  10. return null;
  11. }
  12. const elementActions = {
  13. text: () => element.innerText,
  14. visible: () => {
  15. const { visibility, display } = getComputedStyle(element);
  16. return visibility !== 'hidden' && display !== 'none';
  17. },
  18. invisible: () => {
  19. const { visibility, display } = getComputedStyle(element);
  20. return visibility === 'hidden' || display === 'none';
  21. },
  22. attribute: ({ attrName }) => {
  23. if (!element.hasAttribute(attrName)) return null;
  24. return element.getAttribute(attrName);
  25. },
  26. };
  27. return elementActions[actionType](data);
  28. }
  29. function injectJsCode({ data, refData }) {
  30. return new Promise((resolve, reject) => {
  31. const stateId = nanoid();
  32. sessionStorage.setItem(`automa--${stateId}`, JSON.stringify(refData));
  33. const scriptEl = document.createElement('script');
  34. scriptEl.textContent = `
  35. (async () => {
  36. ${automaRefDataStr(stateId)}
  37. try {
  38. ${data.code}
  39. } catch (error) {
  40. return {
  41. $isError: true,
  42. message: error.message,
  43. }
  44. }
  45. })()
  46. .then((detail) => {
  47. window.dispatchEvent(new CustomEvent('__automa-condition-code__', { detail }));
  48. });
  49. `;
  50. document.body.appendChild(scriptEl);
  51. const handleAutomaEvent = ({ detail }) => {
  52. scriptEl.remove();
  53. window.removeEventListener(
  54. '__automa-condition-code__',
  55. handleAutomaEvent
  56. );
  57. if (detail.$isError) {
  58. reject(new Error(detail.message));
  59. return;
  60. }
  61. resolve(detail);
  62. };
  63. window.addEventListener('__automa-condition-code__', handleAutomaEvent);
  64. });
  65. }
  66. export default async function (data) {
  67. let result = null;
  68. if (data.type.startsWith('element')) {
  69. result = await handleConditionElement(data);
  70. }
  71. if (data.type === 'code') {
  72. result = await injectJsCode(data);
  73. }
  74. return result;
  75. }