Giter VIP home page Giter VIP logo

wdi5's Introduction

we're UI5, folks!

This is the head space of the UI5 community.

wdi5's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wdi5's Issues

Error thrown for complex UI5 Id

Hi,

Some of the elements of the UI5 have complex id naming schema (separated with '.', '::',, '-','--'.)
For such elements, I received below cryptic error. I am not sure how to read this error.

Error

[chrome 97.0.4692.71 windows #0-0] invalid selector: An invalid or illegal selector was specified
  (Session info: chrome=97.0.4692.71)
[chrome 97.0.4692.71 windows #0-0] Backtrace:
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x00316903+2517251]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x002AF8E1+2095329]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x001B2848+1058888]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x001B4F44+1068868]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x001B4E0E+1068558]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x001B5070+1069168]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x001DD1C2+1233346]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x001DD63B+1234491]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x00207812+1406994]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x001F650A+1336586]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x00205BBF+1399743]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x001F639B+1336219]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x001D27A7+1189799]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x001D3609+1193481]
[chrome 97.0.4692.71 windows #0-0]      GetHandleVerifier [0x004A5904+1577972]
[chrome 97.0.4692.71 windows #0-0]      GetHandleVerifier [0x00550B97+2279047]
[chrome 97.0.4692.71 windows #0-0]      GetHandleVerifier [0x003A6D09+534521]
[chrome 97.0.4692.71 windows #0-0]      GetHandleVerifier [0x003A5DB9+530601]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x002B4FF9+2117625]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x002B98A8+2136232]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x002B99E2+2136546]
[chrome 97.0.4692.71 windows #0-0]      Ordinal0 [0x002C3541+2176321]
[chrome 97.0.4692.71 windows #0-0]      BaseThreadInitThunk [0x774DFA29+25]
[chrome 97.0.4692.71 windows #0-0]      RtlGetAppContainerNamedObjectPath [0x77627A9E+286]
[chrome 97.0.4692.71 windows #0-0]      RtlGetAppContainerNamedObjectPath [0x77627A6E+238]
[chrome 97.0.4692.71 windows #0-0]      (No symbol) [0x00000000]
[chrome 97.0.4692.71 windows #0-0]

The Code

let oTableTitle = await browser.asControl({
			selector: {
				id: "xxxxxxxx.view::sap.suite.ui.generic.template.ListReport.view.ListReport::xMMMMMM--listReport-header"
			}
		});
let sTitle = await oTableTitle.getText();

Note:

using WDIO works with below code

const oTableTitle = $(`//*[contains(@id, "xMMMMMM--listReport-header-inner")]`) // wdio-native

However, when same done on WDI5 (i.e. appending -inner at the end of the id), gives an error

Error: [wdi5]call of _getControl() failed because of: Error: No DOM element found using the control selector {"id":{}}

code

 let oTableTitle = await browser.asControl({
			selector: {
				id: /xMMMMMM--listReport-header-inner$/
			}
		});
let sTitle = await oTableTitle.getText();

Find element by partial text (RegEx support for text property)

Hi,
does WDI5 support matching elements by partial text, or RegExpr in the text property?

Our Use Case is: Find elements contaning "Salatteller" text on a given UI5 page.

Details of use case:
We POC a migration from UIVeri5 to WDI5.
We have data created by API with timestamps (like "UIVERI5_AUTO SAP-Style-Salatteller mit Spinat Maultaschen 2021-12-01T12:23:49.444Z"), so we use a lot of partial matching in our tests.

On UIVeri5, we were using following locator:

   var title = element(by.control({
      controlType: 'sap.m.Title',
      properties: {
         text: new RegExp(text)
      }
   }));

This seems not to work on wdi5 :

const title = browser.asControl({
    selector: {
        controlType: 'sap.m.Title',
        properties: {
              text: new RegExp(text)
        }
    }
});

Thanks,
Adrianna

Evaluation failed: DOMException: for List in Dialog

Hello,

we have a very very simple use case. We want to identify a list that is displayed in a dialog. For this we have the following very simple code:

const oSelector = {
        forceSelect: true,
        selector: {
            controlType: "sap.m.List"
        }
    };

const oList = browser.asControl(oSelector);

When we execute this then we get following error:

Evaluation failed: DOMException: Failed to execute 'querySelector' on 'Document': '#success,[object Object],myObject--dlgSelect-list-trigger,getList,getContent,addContent,insertContent,removeContent,removeAllContent,indexOfContent,destroyContent,bindContent,unbindContent,getContentAnnouncement,getType,setType,getUnread,setUnread,getSelected,setSelected,getCounter,setCounter,getHighlight,setHighlight,getAriaLabelledBy,addAriaLabelledBy,removeAriaLabelledBy,removeAllAriaLabelledBy,attachTap,detachTap,fireTap,attachDetailTap,detachDetailTap,fireDetailTap,attachPress,detachPress,firePress,attachDetailPress,detachDetailPress,fireDetailPress,init,invalidate,getBindingContextPath,isSelectedBoundTwoWay,getListProperty,informList,informSelectedChange,getAccessibilityType,getGroupAnnouncement,getAccessibilityDescription,getAccessibilityInfo,getMode,updateAccessibilityState,getDeleteControl,getDetailControl,getNavigationControl,getSingleSelectControl,getMultiSelectControl,getModeControl,getTypeControl,destroyControls,isActionable,exit,isSelectable,isSelected,updateSelectedDOM,setParent,setBindingContext,isGroupHeader,isIncludedIntoSelection,hasActiveType,setActive,ontap,ontouchstart,ontouchmove,ontouchend,ontouchcancel,onsapspace,onsapenter,onsapdelete,onkeydown,getTabbables,onsaptabnext,onsaptabprevious,onfocusin,onsapup,oncontextmenu,onsapdown,getBlocked,setBlocked,getBusy,setBusy,getBusyIndicatorDelay,setBusyIndicatorDelay,getBusyIndicatorSize,setBusyIndicatorSize,getVisible,setVisible,getFieldGroupIds,setFieldGroupIds,attachValidateFieldGroup,detachValidateFieldGroup,fireValidateFieldGroup,clone,addStyleClass,removeStyleClass,toggleStyleClass,hasStyleClass,isActive,rerender,getDomRef,allowTextSelection,attachBrowserEvent,detachBrowserEvent,placeAt,onselectstart,getIdForLabel,destroy,isBusy,getControlsByFieldGroupId,checkFieldGroupIds,triggerValidateFieldGroup,getTooltip,setTooltip,destroyTooltip,getCustomData,addCustomData,insertCustomData,removeCustomData,removeAllCustomData,indexOfCustomData,destroyCustomData,getLayoutData,setLayoutData,destroyLayoutData,getDependents,addDependent,insertDependent,removeDependent,removeAllDependents,indexOfDependent,destroyDependents,getDragDropConfig,addDragDropConfig,insertDragDropConfig,removeDragDropConfig,removeAllDragDropConfig,indexOfDragDropConfig,destroyDragDropConfig,getInterface,toString,prop,getUIArea,fireEvent,addDelegate,removeDelegate,addEventDelegate,removeEventDelegate,getFocusDomRef,focus,getFocusInfo,applyFocusInfo,getTooltip_AsString,getTooltip_Text,data,findElements,bindElement,unbindElement,getElementBinding,getDomRefForSetting,register,deregister,attachValidationSuccess,detachValidationSuccess,fireValidationSuccess,attachValidationError,detachValidationError,fireValidationError,attachParseError,detachParseError,fireParseError,attachFormatError,detachFormatError,fireFormatError,attachModelContextChange,detachModelContextChange,fireModelContextChange,applySettings,getId,setProperty,getProperty,validateProperty,isPropertyInitial,resetProperty,getOriginInfo,setAssociation,getAssociation,addAssociation,removeAssociation,removeAllAssociation,validateAggregation,setAggregation,indexOfAggregation,insertAggregation,addAggregation,removeAggregation,removeAllAggregation,destroyAggregation,isInvalidateSuppressed,getParent,isBinding,extractBindingInfo,getBindingInfo,bindObject,bindContext,unbindContext,unbindObject,bindProperty,unbindProperty,updateProperty,updateModelProperty,bindAggregation,unbindAggregation,updateAggregation,refreshAggregation,propagateMessages,isTreeBinding,updateBindings,isBound,getObjectBinding,getEventingParent,getBinding,getBindingPath,setElementBindingContext,updateBindingContext,getBindingContext,setModel,addPropagationListener,removePropagationListener,getPropagationListeners,propagateProperties,getModel,hasModel,findAggregatedObjects,attachEvent,attachEventOnce,detachEvent,hasListeners,isA,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,valueOf,toLocaleString,__executeElement_1,success,[object Object],ylpplfilialauswlib--dlgSelect-list-trigger,getList,getContent,addContent,insertContent,removeContent,removeAllContent,indexOfContent,destroyContent,bindContent,unbindContent,getContentAnnouncement,getType,setType,getUnread,setUnread,getSelected,setSelected,getCounter,setCounter,getHighlight,setHighlight,getAriaLabelledBy,addAriaLabelledBy,removeAriaLabelledBy,removeAllAriaLabelledBy,attachTap,detachTap,fireTap,attachDetailTap,detachDetailTap,fireDetailTap,attachPress,detachPress,firePress,attachDetailPress,detachDetailPress,fireDetailPress,init,invalidate,getBindingContextPath,isSelectedBoundTwoWay,getListProperty,informList,informSelectedChange,getAccessibilityType,getGroupAnnouncement,getAccessibilityDescription,getAccessibilityInfo,getMode,updateAccessibilityState,getDeleteControl,getDetailControl,getNavigationControl,getSingleSelectControl,getMultiSelectControl,getModeControl,getTypeControl,destroyControls,isActionable,exit,isSelectable,isSelected,updateSelectedDOM,setParent,setBindingContext,isGroupHeader,isIncludedIntoSelection,hasActiveType,setActive,ontap,ontouchstart,ontouchmove,ontouchend,ontouchcancel,onsapspace,onsapenter,onsapdelete,onkeydown,getTabbables,onsaptabnext,onsaptabprevious,onfocusin,onsapup,oncontextmenu,onsapdown,getBlocked,setBlocked,getBusy,setBusy,getBusyIndicatorDelay,setBusyIndicatorDelay,getBusyIndicatorSize,setBusyIndicatorSize,getVisible,setVisible,getFieldGroupIds,setFieldGroupIds,attachValidateFieldGroup,detachValidateFieldGroup,fireValidateFieldGroup,clone,addStyleClass,removeStyleClass,toggleStyleClass,hasStyleClass,isActive,rerender,getDomRef,allowTextSelection,attachBrowserEvent,detachBrowserEvent,placeAt,onselectstart,getIdForLabel,destroy,isBusy,getControlsByFieldGroupId,checkFieldGroupIds,triggerValidateFieldGroup,getTooltip,setTooltip,destroyTooltip,getCustomData,addCustomData,insertCustomData,removeCustomData,removeAllCustomData,indexOfCustomData,destroyCustomData,getLayoutData,setLayoutData,destroyLayoutData,getDependents,addDependent,insertDependent,removeDependent,removeAllDependents,indexOfDependent,destroyDependents,getDragDropConfig,addDragDropConfig,insertDragDropConfig,removeDragDropConfig,removeAllDragDropConfig,indexOfDragDropConfig,destroyDragDropConfig,getInterface,toString,prop,getUIArea,fireEvent,addDelegate,removeDelegate,addEventDelegate,removeEventDelegate,getFocusDomRef,focus,getFocusInfo,applyFocusInfo,getTooltip_AsString,getTooltip_Text,data,findElements,bindElement,unbindElement,getElementBinding,getDomRefForSetting,register,deregister,attachValidationSuccess,detachValidationSuccess,fireValidationSuccess,attachValidationError,detachValidationError,fireValidationError,attachParseError,detachParseError,fireParseError,attachFormatError,detachFormatError,fireFormatError,attachModelContextChange,detachModelContextChange,fireModelContextChange,applySettings,getId,setProperty,getProperty,validateProperty,isPropertyInitial,resetProperty,getOriginInfo,setAssociation,getAssociation,addAssociation,removeAssociation,removeAllAssociation,validateAggregation,setAggregation,indexOfAggregation,insertAggregation,addAggregation,removeAggregation,removeAllAggregation,destroyAggregation,isInvalidateSuppressed,getParent,isBinding,extractBindingInfo,getBindingInfo,bindObject,bindContext,unbindContext,unbindObject,bindProperty,unbindProperty,updateProperty,updateModelProperty,bindAggregation,unbindAggregation,updateAggregation,refreshAggregation,propagateMessages,isTreeBinding,updateBindings,isBound,getObjectBinding,getEventingParent,getBinding,getBindingPath,setElementBindingContext,updateBindingContext,getBindingContext,setModel,addPropagationListener,removePropagationListener,getPropagationListeners,propagateProperties,getModel,hasModel,findAggregatedObjects,attachEvent,attachEventOnce,detachEvent,hasListeners,isA,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,valueOf,toLocaleString,success,[object Object],ylpplfilialauswlib--dlgSelect-list-trigger,getList,getContent,addContent,insertContent,removeContent,removeAllContent,indexOfContent,destroyContent,bindContent,unbindContent,getContentAnnouncement,getType,setType,getUnread,setUnread,getSelected,setSelected,getCounter,setCounter,getHighlight,setHighlight,getAriaLabelledBy,addAriaLabelledBy,removeAriaLabelledBy,removeAllAriaLabelledBy,attachTap,detachTap,fireTap,attachDetailTap,detachDetailTap,fireDetailTap,attachPress,detachPress,firePress,attachDetailPress,detachDetailPress,fireDetailPress,init,invalidate,getBindingContextPath,isSelectedBoundTwoWay,getListProperty,informList,informSelectedChange,getAccessibilityType,getGroupAnnouncement,getAccessibilityDescription,getAccessibilityInfo,getMode,updateAccessibilityState,getDeleteControl,getDetailControl,getNavigationControl,getSingleSelectControl,getMultiSelectControl,getModeControl,getTypeControl,destroyControls,isActionable,exit,isSelectable,isSelected,updateSelectedDOM,setParent,setBindingContext,isGroupHeader,isIncludedIntoSelection,hasActiveType,setActive,ontap,ontouchstart,ontouchmove,ontouchend,ontouchcancel,onsapspace,onsapenter,onsapdelete,onkeydown,getTabbables,onsaptabnext,onsaptabprevious,onfocusin,onsapup,oncontextmenu,onsapdown,getBlocked,setBlocked,getBusy,setBusy,getBusyIndicatorDelay,setBusyIndicatorDelay,getBusyIndicatorSize,setBusyIndicatorSize,getVisible,setVisible,getFieldGroupIds,setFieldGroupIds,attachValidateFieldGroup,detachValidateFieldGroup,fireValidateFieldGroup,clone,addStyleClass,removeStyleClass,toggleStyleClass,hasStyleClass,isActive,rerender,getDomRef,allowTextSelection,attachBrowserEvent,detachBrowserEvent,placeAt,onselectstart,getIdForLabel,destroy,isBusy,getControlsByFieldGroupId,checkFieldGroupIds,triggerValidateFieldGroup,getTooltip,setTooltip,destroyTooltip,getCustomData,addCustomData,insertCustomData,removeCustomData,removeAllCustomData,indexOfCustomData,destroyCustomData,getLayoutData,setLayoutData,destroyLayoutData,getDependents,addDependent,insertDependent,removeDependent,removeAllDependents,indexOfDependent,destroyDependents,getDragDropConfig,addDragDropConfig,insertDragDropConfig,removeDragDropConfig,removeAllDragDropConfig,indexOfDragDropConfig,destroyDragDropConfig,getInterface,toString,prop,getUIArea,fireEvent,addDelegate,removeDelegate,addEventDelegate,removeEventDelegate,getFocusDomRef,focus,getFocusInfo,applyFocusInfo,getTooltip_AsString,getTooltip_Text,data,findElements,bindElement,unbindElement,getElementBinding,getDomRefForSetting,register,deregister,attachValidationSuccess,detachValidationSuccess,fireValidationSuccess,attachValidationError,detachValidationError,fireValidationError,attachParseError,detachParseError,fireParseError,attachFormatError,detachFormatError,fireFormatError,attachModelContextChange,detachModelContextChange,fireModelContextChange,applySettings,getId,setProperty,getProperty,validateProperty,isPropertyInitial,resetProperty,getOriginInfo,setAssociation,getAssociation,addAssociation,removeAssociation,removeAllAssociation,validateAggregation,setAggregation,indexOfAggregation,insertAggregation,addAggregation,removeAggregation,removeAllAggregation,destroyAggregation,isInvalidateSuppressed,getParent,isBinding,extractBindingInfo,getBindingInfo,bindObject,bindContext,unbindContext,unbindObject,bindProperty,unbindProperty,updateProperty,updateModelProperty,bindAggregation,unbindAggregation,updateAggregation,refreshAggregation,propagateMessages,isTreeBinding,updateBindings,isBound,getObjectBinding,getEventingParent,getBinding,getBindingPath,setElementBindingContext,updateBindingContext,getBindingContext,setModel,addPropagationListener,removePropagationListener,getPropagationListeners,propagateProperties,getModel,hasModel,findAggregatedObjects,attachEvent,attachEventOnce,detachEvent,hasListeners,isA,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,valueOf,toLocaleString' is not a valid selector.

[Chrome 89.0.4389.114 darwin #0-0]     at ExecutionContext._evaluateInternal (/node_modules/puppeteer-core/lib/cjs/puppeteer/common/ExecutionContext.js:218:19)
[Chrome 89.0.4389.114 darwin #0-0]     at processTicksAndRejections (node:internal/process/task_queues:94:5)
[Chrome 89.0.4389.114 darwin #0-0]     at async ElementHandle.evaluateHandle (yrtbfinv/node_modules/puppeteer-core/lib/cjs/puppeteer/common/JSHandle.js:120:16)
[Chrome 89.0.4389.114 darwin #0-0]     at async Object.internalHandler.queryOne (/node_modules/puppeteer-core/lib/cjs/puppeteer/common/QueryHandler.js:24:30)
[Chrome 89.0.4389.114 darwin #0-0]     at async DOMWorld.$ (/node_modules/puppeteer-core/lib/cjs/puppeteer/common/DOMWorld.js:95:23)
[Chrome 89.0.4389.114 darwin #0-0]     at async DevToolsDriver.findElement (/node_modules/devtools/build/utils.js:88:15)
[Chrome 89.0.4389.114 darwin #0-0]     at async Browser.wrappedCommand (node_modules/devtools/build/devtoolsdriver.js:75:26)
[Chrome 89.0.4389.114 darwin #0-0]     at global.$ (/node_modules/@wdio/runner/build/index.js:181:42)
[Chrome 89.0.4389.114 darwin #0-0]     at WDI5._getControl (/node_modules/wdio-ui5-service/src/lib/WDI5.js:574:45)
[Chrome 89.0.4389.114 darwin #0-0]     at new WDI5 (/node_modules/wdio-ui5-service/src/lib/WDI5.js:36:36)
[Chrome 89.0.4389.114 darwin #0-0]     at Browser.<anonymous> (/node_modules/wdio-ui5-service/src/lib/wdioUi5-index.js:467:33)
[Chrome 89.0.4389.114 darwin #0-0]     at Browser.next [as asControl] (/node_modules/@wdio/utils/build/monad.js:149:33)

Looks like a bug in WDI5. The library was presented at the UI5 Con. Is this production ready or rather beta stage?

Regards,
Nils

inconsistent behaviour in get$Shorthand (getItems, getContent, etc.)

Very annoying bug if you want to the the first entry as WDI5 object of an aggregation - it isn't possible at the moment.

If I call getContent(0) on a sap.m.Page WDI5 object, I get an array of objects each containing the attribute 'id'. This is the same behavior as getContent(true).
If I call getContent(1) I would get the WDI5 object. Please fix this bug or make an exception in the README.md (or is it documented?)

I previously thought this could be related to webdriver/sync and stuff. I know the value '0' is considered as falsy, but as argument you could easily compare the input type and concrete value.

Runtime Env (please complete the following information):

  • wdi5/wdio-ui5-service- 0.8.1
  • UI5 version: 1.71.41
  • wdio-version (output of wdio --version): 7.16.14
  • node-version (output of node --version): v16.13.2
  • OS: Mac OS X
  • Browser + Version: chrome 97.0.4692.99

Bug: ui5 service not loaded correctly with version 0.0.3

This is in my wdio.conf.js file. I am using wdi5 version 0.0.3.

exports.config = {
    // ...
    services: ['ui5'],
    // ...
}

On startup wdio throws an error because it cannot identify wdio-ui5-service as the service behind the keyword ui5.

 ERROR @wdio/utils:initialiseServices: Error: Couldn't find plugin "ui5" service, neither as wdio scoped package "@wdio/ui5-service" nor as community package "wdio-ui5-service". Please make sure you have it installed!

I think this is related to some internal refactoring for version 0.0.3 that removed the launcher. According to the documentation (https://webdriver.io/docs/customservices.html), this might still be necessary?!

It works, when I directly include the service class (like you do it in the tests):

const ui5Service = require('wdio-ui5-service/src/index')

exports.config = {
    // ...
    services: [
        [ui5Service]
    ],
    // ...
}

Cannot use ui5 methods on ComboBox

Hello

I cannot get ComboBox control to use UI5 methods like getItems(). Trying to call it throws getItems is not a function.
Seems like browser.asControl returns a reference to the ComboBox arrow. Tried to use id of the control but it always returns the arrow itself that simply doesn't have the method.

Somehow same I stumble upon same errors trying to access sap.m.Table.getMode() or even .getId(). At the same time sap.m.Input.setValue() or sap.m.CheckBox.setSelected() works just fine. Was following the example provided in fluent async api section.

Am I doing it wrong?

Fragment of my code

await browser.asControl({
    interaction: 'root',
    selector: {
        controlType: 'sap.m.ComboBox',
        id: /.*boardArea$/
    }
}).getItems()

Feature Request: Add command to reinitialize wdi5

In my cucumber files there are multiple tests (cucumber scenarios) in one browser session, that all do some routing, some with UI5, some without (e.g. login page -> access launchpad -> access app -> check -> logout page, login page -> access launchpadโ€ฆ
The first test runs fine but subsequent tests fail due to some wdi5 internal error (_context is not set and thus _context.waitForUI5() fails).
I got things running with a custom command, but reseting the internals from the outside doesnโ€™t seem the best way to go:

browser.addCommand("resetUI5",  () => {
  // UI5 bridge setup
  const context = driver ? driver : browser;
  driver.execute(() => {
    window.bridge = null;
  });
  const wdi5config = context.config.wdi5;
  wdioUI5.injectUI5(context);
  wdioUI5.setup(context);
});

Maybe you can add a similar command that makes it possible to fully reinitialize wdi5 or make waitForUI5 check if all the internals are still valid and if not, do some automated reinitialization.

Fetch multiple elements ($$)

Hi,

is this possible to select multiple elements in wdi5? (Similar to wdio $$ notation and uiveri5 element.all feature)

We are using following locators in UIVeri5 and looking for a replacement

 element.all(by.control({
   controlType: 'sap.m.Title'
}))

or WDIO

get allTitles_WDIO() { return $$('.sapMTitle')}

Thanks
Adrianna

Failed to get count of items in a sap.m.Table

Hi Experts,

In my test, I tried to assert the count of items in a sap.m.Table.

Firstly I tried it like this:

const table = browser.asControl({
    selector: {
        id: "idDetailTable",
        viewName: "deleteDataSubjects.view.Detail"
    }
});
const items = table.getItems();
expect(items.length).toBe(1);

But I got the following error:
image

When I debug it, I could see that I successfully got the table object:
image

But it didn't generate the "getItems" method:
image

Then I tried this:

const table = browser.asControl({
    selector: {
        id: "idDetailTable",
        viewName: "deleteDataSubjects.view.Detail"
    }
});
const items = table.getAggregation("items");
expect(items.length).toBe(1);

I could successfully get the items as [] and the assertion failed:
image

I got the selector of the table from the test recorder:
image

Some other hint: the data resource of the table is OData, e.g. one cell of it is like:

{
        controlType: "sap.m.ObjectStatus",
        viewName: "deleteDataSubjects.view.Detail",
        bindingPath: {
            path: "/ResidenceExpiredDataSubjects(jobID='9223372036854775807',dataSubjectGuid='1641982475494')",
            propertyPath: "dataSubjectID",
            modelName: "mainODataModel"
        }
    }

Thank you and best regards,
Cong

In Docker , test fails with an error

Hi,

When executing the spec locally on my machine , the test executed with 100% success.
However, when the same spec is executed in a Docker container it ends with the below result.
image

I am not an expert at docker. However, I believe a test working in one machine should work same way in the Docker.

Some observations :

  • I execute twice or thrice all every time its the same result
    • The screenshots taken by timeline-reporter is capturing the failing step however the image is corrupted.

image

  • Other step's screenshot images are well captured.

Discussion - resync after action feature

Hello,

When i am using wdi5 to trigger an action like:
browser.asControl(inputSelector).enterText('new Text');
It is possible that webrequests etc are triggered when the action is fired.

We have a setup where the webapplication is hitting a mockserver that runs in the same context as the tests.
So we can write something like
assert(requests.done()).toBe(true)
If that is done, the test might fail, since the command that is entering the text does not wait until new async processes introduced by the action are done.

If you like wdi5 could sync again after an action, using an empty Opa5 waitFor with automatic waiting to true.

This way you can also track performance better. Since the time spend actually shows on the action that enters the text and not on the next action that is taking over the sync from the previous one.

Let me know if you think it is a good way to provide this as a pull request.

No 'inputToValidate' given but it is a mandatory parameter

I am currently trying to integrate WDI5 into my project. Currently WDIO is started via the web browser.

The start page is the Fiori Launchpad. Then I navigate to the app using browser.goTo({sHash: '#MyFioriObject-display'});.

Now I just want to get a control at the beginning. For this I wrote the following code.

    const oSelector = { 
        selector: {
            id: 'input',
            controlType: 'sap.m.Input'
        }
    };
 
    const control = browser.asControl(oSelector);

I already tried to add the view or to try other elements but I always get the following error. I even get the error if I want to get an button or an view.

Evaluation failed: Error: sap.ui.test.autowaiter._autoWaiterAsync#extendConfig - No 'inputToValidate' given but it is a mandatory parameter
at _validate (https://sapui5.hana.ondemand.com/1.60.31/resources/sap/ui/test/_ParameterValidator.js?eval:6:509)
at _.validate (https://sapui5.hana.ondemand.com/1.60.31/resources/sap/ui/test/_ParameterValidator.js?eval:6:371)
at v (https://sapui5.hana.ondemand.com/1.60.31/resources/sap/ui/test/autowaiter/_autoWaiterAsync.js?eval:6:1253)
at Object.e [as extendConfig] (https://sapui5.hana.ondemand.com/1.60.31/resources/sap/ui/test/autowaiter/_autoWaiterAsync.js?eval:6:466)
at Function.R.waitForUI5 (https://sapui5.hana.ondemand.com/1.60.31/resources/sap/ui/test/RecordReplay.js?eval:6:1935)
at eval (eval at (:20:16), :3:18)
at eval (eval at (:20:16), :24:12)
at puppeteer_evaluation_script:20:16
at puppeteer_evaluation_script:2:12
Error: Evaluation failed: Error: sap.ui.test.autowaiter._autoWaiterAsync#extendConfig - No 'inputToValidate' given but it is a mandatory parameter
at ExecutionContext._evaluateInternal (XXX\node_modules\puppeteer-core\lib\cjs\puppeteer\common\ExecutionContext.js:217:19)
at runMicrotasks ()
at processTicksAndRejections (node:internal/process/task_queues:93:5)
at async ExecutionContext.evaluate (XXX\node_modules\puppeteer-core\lib\cjs\puppeteer\common\ExecutionContext.js:106:16)
at async ElementHandle.evaluate (XXX\node_modules\puppeteer-core\lib\cjs\puppeteer\common\JSHandle.js:102:16)
at async ElementHandle.$eval (XXX\node_modules\puppeteer-core\lib\cjs\puppeteer\common\JSHandle.js:650:24)
at async DevToolsDriver.executeAsyncScript (XXX\node_modules\devtools\build\commands\executeAsyncScript.js:19:20)
at async Browser.wrappedCommand (XXX\node_modules\devtools\build\devtoolsdriver.js:62:26)
at async Browser.runCommandWithHooks (XXX\node_modules@wdio\sync\build\wrapCommand.js:70:25)
at Browser.runCommandWithHooks (XXX\node_modules@wdio\sync\build\wrapCommand.js:65:24)
at Browser.wrapCommandFn (XXX\node_modules@wdio\sync\build\wrapCommand.js:44:44)
at Browser.executeAsync (XXX\node_modules\webdriverio\build\commands\browser\executeAsync.js:11:17)
at Browser.runCommandWithHooks (XXX\node_modules@wdio\sync\build\wrapCommand.js:70:34)
at WDI5._getControl (XXX\node_modules\wdio-ui5-service\src\lib\WDI5.js:508:32)
at new WDI5 (XXX\node_modules\wdio-ui5-service\src\lib\WDI5.js:36:36)
at Browser. (XXX\node_modules\wdio-ui5-service\src\lib\wdioUi5-index.js:467:33)
at XXX\node_modules@wdio\sync\build\runFnInFiberContext.js:13:35
at Browser.asControl (XXX\node_modules@wdio\sync\build\wrapCommand.js:44:44)
at Browser.next [as asControl] (XXX\node_modules@wdio\utils\build\monad.js:95:33)
at World. (XXX\webapp\test\steps\Test.js:27:29)
at World.executeSync (XXX\node_modules@wdio\sync\build\index.js:25:22)
at XXX\node_modules@wdio\sync\build\index.js:46:68

Why and how can I fix it?

Thanks in advance!

Regards,
Nils

[Question] Is it possible to assert a UI5 control is invisible

Hi Experts,

I'm new to WDI5, I was trying to assert a UI5 control is not visible on UI, but it didn't work.

var input= browser.asControl({
            selector: {
                id: "myInput",
                viewName: "myView",
                visible: false
            }
        });

        expect(input.getVisible()).toBe(false);

It seems that I can only assert visible controls, but not invisible ones?

Thank you and best regards.

How to resolve error : [wdi5] bridge was not initialized correctly

Describe the bug
Receiving below error several times at the beginning of the test code execution.
My test cases passed successfully though.
Could this message be resolved or suppressed.

Code

      const elem = await $('#meAreaHeaderButton')
      await elem.waitForDisplayed({ timeout: 3000 });

      const _ui5Service = require('wdio-ui5-service').default
      const wdioUI5Service = new _ui5Service()
      wdioUI5Service.injectUI5()

After this statement the error is raised several times in a row, before the actual actions/assertions are executed.

Logs/Console Output

[0-0] [wdi5] bridge was not initialized correctly
[0-0] 2022-01-25T12:55:45.974Z ERROR @wdio/utils:shim: Error: [wdi5]bridge was not initialized correctly
[0-0]     at Object.error (C:\Users\MyUser\git\MyUser\wdi5_resmon\node_modules\wdio-ui5-service\src\lib\Logger.js:77:19)
[0-0]     at Object.injectUI5 (C:\Users\MyUser\git\MyUser\wdi5_resmon\node_modules\wdio-ui5-service\src\lib\wdioUi5-index.js:283:16)
[0-0]     at processTicksAndRejections (internal/process/task_queues.js:95:5)
[0-0]     at async Service.injectUI5 (C:\Users\MyUser\git\MyUser\wdi5_resmon\node_modules\wdio-ui5-service\src\service.js:62:9)
[0-0]     at async Service.startWDI5 (C:\Users\MyUser\git\MyUser\wdi5_resmon\node_modules\wdio-ui5-service\src\service.js:49:13)
[0-0]     at async Service.before (C:\Users\MyUser\git\MyUser\wdi5_resmon\node_modules\wdio-ui5-service\src\service.js:6:9)
[0-0]     at async Promise.all (index 0)
[0-0]     at async executeHooksWithArgsShim (C:\Users\MyUser\git\MyUser\wdi5_resmon\node_modules\@wdio\utils\build\shim.js:101:20)
[0-0]     at async Runner.run (C:\Users\MyUser\git\MyUser\wdi5_resmon\node_modules\@wdio\runner\build\index.js:99:9)

Runtime Env (please complete the following information):

  • wdi5/wdio-ui5-service-version: 0.8.1
  • wdio-version : 7.16.12
  • node-version : 14.17.4
  • OS: WIN10
  • Browser + Version : ChromeDriver 96.0.4664.45

fix iOS build

iOS Build fails because of

  • wk webview

-> CORS is enabled for the application

createControlIdMap supports only arrays

Currently the method "createControlIdMap" supports only arrays.
The method getAggregation of a control instead (e.g. in _getAggregation) could return only one element as well.
For this case it breaks.

wdi5 fluent async api vs wdio async api

Hi @vobu , the async api works quite well! ๐Ÿ‘ One thing I found is, seems that a fluent "click" is not supported yet.

This one work:

const button = await myButton.getWebElement();
await myButton.click();

This one is not working:

await myButton.getWebElement().click();

Error:
image

Originally posted by @cwang1221 in #104 (reply in thread)

Take Screenshots Crashs with waitForUI5 of undefined

Hello,
we want to use WDI5 for our tests with Cucumber. For this we have built a relatively simple test setup. First the launchpad is started and then the app is to be loaded.

This works fine locally. Unfortunately, in the pipeline the app is not loaded and therefore the browser title does not change. To better analyze the problem we wanted to try the screenshot function of WDI5. Unfortunately, this immediately crashes with the following error. The screenshot function is locally and in the pipeline not working.

Why? What are we doing wrong?

Thanks and best regards
Nils

Error log:

2021-04-07T10:23:22.556Z DEBUG @wdio/utils:initialiseServices: initialise service "ui5" as NPM package
2021-04-07T10:23:22.567Z INFO @wdio/cli:launcher: Run onPrepare hook
2021-04-07T10:23:22.568Z DEBUG @wdio/cli:utils: Finished to run "onPrepare" hook in 0ms
2021-04-07T10:23:22.569Z INFO @wdio/cli:launcher: Run onWorkerStart hook
2021-04-07T10:23:22.569Z DEBUG @wdio/cli:utils: Finished to run "onWorkerStart" hook in 0ms
2021-04-07T10:23:22.570Z INFO @wdio/local-runner: Start worker 0-0 with arg: 
[0-0] 2021-04-07T10:23:23.315Z INFO @wdio/local-runner: Run worker command: run
[0-0] 2021-04-07T10:23:23.534Z DEBUG @wdio/config:utils: Found 'ts-node' package, auto-compiling TypeScript files
[0-0] 2021-04-07T10:23:23.537Z DEBUG @wdio/local-runner:utils: init remote session
[0-0] 2021-04-07T10:23:23.543Z DEBUG @wdio/utils:initialiseServices: initialise service "ui5" as NPM package

.....

[0-0] 2021-04-07T10:23:30.344Z DEBUG @wdio/local-runner:utils: init remote session
[0-0] 2021-04-07T10:23:30.345Z INFO devtools:puppeteer: Initiate new session using the DevTools protocol
[0-0] 2021-04-07T10:23:30.346Z INFO devtools: Launch Google Chrome with flags: --enable-automation --disable-popup-blocking --disable-extensions --disable-background-networking --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-sync --metrics-recording-only --disable-default-apps --mute-audio --no-first-run --no-default-browser-check --disable-hang-monitor --disable-prompt-on-repost --disable-client-side-phishing-detection --password-store=basic --use-mock-keychain --disable-component-extensions-with-background-pages --disable-breakpad --disable-dev-shm-usage --disable-ipc-flooding-protection --disable-renderer-backgrounding --force-fieldtrials=*BackgroundTracing/default/ --enable-features=NetworkService,NetworkServiceInProcess --disable-features=site-per-process,TranslateUI,BlinkGenPropertyTrees --window-position=0,0 --window-size=1200,900 --headless --disable-gpu --no-sandbox --disable-dev-shm-usage --disable-browser-side-navigation --window-size=1920,1080
[0-0] 2021-04-07T10:23:30.911Z INFO devtools: Connect Puppeteer with browser on port 50172
[0-0] open url with fallback (this is not causing any issues since its is removed for navigation): #
[0-0] 2021-04-07T10:23:31.113Z INFO devtools: COMMAND navigateTo("http://localhost:3000/#")
[0-0] 2021-04-07T10:23:34.190Z INFO devtools: RESULT null
[0-0] wdio-ui5-service before hook
[0-0] creating internal control map
[0-0] 2021-04-07T10:23:34.194Z INFO devtools: COMMAND executeAsyncScript("return ((done) => {
                setTimeout(() => {
                    if (document.location.href != 'data:,') {
                        // make sure we are not on the initial page
                        done(document.readyState);
                    }
                }, 400);
            }).apply(null, arguments)", <object>)
[0-0] 2021-04-07T10:23:35.114Z INFO devtools: RESULT complete
[0-0] 2021-04-07T10:23:35.151Z INFO devtools: COMMAND executeScript("return (() => {
        // browser context - you may not access client or console
        return !!window.sap;
    }).apply(null, arguments)", <object>)
[0-0] 2021-04-07T10:23:35.168Z INFO devtools: RESULT true
[0-0] sucessfully initialized wdio-ui5 bridge
[0-0] 2021-04-07T10:23:35.170Z DEBUG @wdio/sync: Finished to run "before" hook in 4061ms

.....

[0-0] 2021-04-07T10:23:49.312Z INFO webdriver: COMMAND screenshot("some-id")
[0-0] 2021-04-07T10:23:49.317Z INFO devtools: COMMAND executeAsyncScript("return ((done) => {
            window.bridge
                .waitForUI5()
                .then(() => {
                    window.wdi5.Log.info('[browser wdi5] UI5 is ready');
                    done(true);
                })
                .catch((error) => {
                    console.error(error);
                });
        }).apply(null, arguments)", <object>)
[0-0] Error in "0: die App geladen ist"
waitUntil condition failed with the following reason: Evaluation failed: TypeError: Cannot read property 'waitForUI5' of undefined
    at eval (eval at <anonymous> (:20:16), <anonymous>:3:18)
    at eval (eval at <anonymous> (:20:16), <anonymous>:11:12)
    at __puppeteer_evaluation_script__:20:16
    at new Promise (<anonymous>)
    at __puppeteer_evaluation_script__:2:12
Error: waitUntil condition failed with the following reason: Evaluation failed: TypeError: Cannot read property 'waitForUI5' of undefined
    at eval (eval at <anonymous> (:20:16), <anonymous>:3:18)
    at eval (eval at <anonymous> (:20:16), <anonymous>:11:12)
    at __puppeteer_evaluation_script__:20:16
    at __puppeteer_evaluation_script__:2:12
    at /..../node_modules/webdriverio/src/commands/browser/waitUntil.ts:79:15
    at World.<anonymous> 

Our wdio.conf.js is the following:

const dynamicConfig = {};

if (process.env.CI) {
    dynamicConfig.port = 9515;
    dynamicConfig.path = '/';
    dynamicConfig.services = ["chromedriver", "ui5"];
} else {
    dynamicConfig.automationProtocol = "devtools";
    dynamicConfig.services = ["ui5"];
}

exports.config = Object.assign({},{

    runner: 'local',

    specs: [
        './features/**/*.feature'
    ],

    maxInstances: 1,
    capabilities: [{
        browserName: 'chrome',
        'goog:chromeOptions': {
            args: ['--headless', '--disable-gpu',
                   '--no-sandbox', '--disable-dev-shm-usage',
                   '--disable-browser-side-navigation', '--window-size=1920,1080']
        },
        acceptInsecureCerts: true
    }],

    bail: 0,

    baseUrl: 'http://localhost:3000/',

    waitforTimeout: 10000,

    connectionRetryTimeout: 120000,

    connectionRetryCount: 3,

    framework: 'cucumber',
    reporters: ['spec',
        ['junit', {
            outputDir: "./0_wdioTestResults",
            outputFileFormat: function (options) {
                return `results-${options.cid}.xml`;
            }
        }]
    ],

    cucumberOpts: {
        // <string[]> (file/dir) require files before executing features
        require: ['./webapp/test/steps/**/*.js'],
        // <boolean> show full backtrace for errors
        backtrace: true,
        // <string[]> ("extension:module") require files with the given EXTENSION after requiring MODULE (repeatable)
        requireModule: [],
        // <boolean> invoke formatters without executing steps
        dryRun: false,
        // <boolean> abort the run on first failure
        failFast: false,
        // <string[]> (type[:path]) specify the output format, optionally supply PATH to redirect formatter output (repeatable)
        format: ['pretty'],
        // <boolean> hide step definition snippets for pending steps
        snippets: true,
        // <boolean> hide source uris
        source: true,
        // <string[]> (name) specify the profile to use
        profile: [],
        // <boolean> fail if there are any undefined or pending steps
        strict: false,
        // <string> (expression) only execute the features or scenarios with tags matching the expression
        tagExpression: '',
        // <number> timeout for step definitions
        timeout: 60000,
        // <boolean> Enable this config to treat undefined definitions as warnings.
        ignoreUndefinedDefinitions: false
    },

    wdi5: {
        screenshotPath: './screenshots/', // [optional] using the project root
        screenshotsDisabled: false,
        logLevel: 'trace',
        platform: 'browser', // [mandatory] browser | android | ios | electron
        url: '', // [mandatory, not empty] path to your bootstrap html file. If your server autoredirects to a 'domain:port/' like root url use empty string ''
        deviceType: 'web', // [mandatory] native | web
        skipInjectUI5OnStart: false // [optional] true when UI5 is not on the start page, you need to later call <wdioUI5service>.injectUI5(); manually
    },

    beforeSession: function (config, capabilities, specs) {
        //Start Testserver
    },

    beforeFeature: function (uri, feature, scenarios) {
        browser.url("/");
        const pageTitle = browser.getTitle();
        if (pageTitle !== 'sLokales Launchpad') {
            console.error(`Fiori Launchpad is not up, found ${pageTitle}`);
            console.log(browser.getPageSource());
            process.exit(1);
        }
    },
    afterSession: function (config, capabilities, specs) {
        //Kill Testserver
    }
}, dynamicConfig);

The step implementation the following:

const { Given, When, Then } = require('@cucumber/cucumber');

Given(/Ich starte die App/, function() {
    browser.url("#MyFioriObject-display");
    browser.refresh();
});

When(/die App geladen ist/, function() {
    browser.waitUntil( () => {
        browser.screenshot('some-id');
        return browser.getTitle() === "MyAppName";

refactor: $control.firePress() โ†’ $control.press

$control.firePress() is considered bad practice as it may lead to side effects during the event lifecycle.
additionally, the internal control logic for the event is not triggered.
ex: $listItem.firePress() doesn't highlight the item in the list - as opposed to a regular click, which has that effect.
โ†’ provide a $control.press() event
thanks for reporting @Siolto!

Unexpected Token '.' Error. This is due to several uses of Optional Chaining which requires Node.js 14

Describe the bug
Error: couldn't initialise "wdio-ui5-service".
SyntaxError: Unexpected token '.'

After hours of debugging I realized that the error was due to the use of Optional Chaining which is unsupported until Node 14 while the readme states "12.x" as a prerequisite.

Optional Chaining was found in the following files:
service.js
lib/WDI5.js
lib/wdioUi5-index.js

example: "Logger.setLoglevel(wdi5config?.logLevel || 'error')"

To Reproduce
Run wdio-ui5-service with Node.js 12 to reproduce

Resources:
https://stackoverflow.com/questions/59574047/how-to-use-optional-chaining-in-node-js-12
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining

Working with ancestor in selector

Hi,
We would like to migrate from another tool.
We have a lot of element selector using the ancestor due to a complex tree of elements.
Is will be possible to have such as propertie now or in the futur? Or if not, how we can write our wdio scripts to easely find our element by their parents (potentially nested)
Thanks a lot,
ND

call of _getControl() failed for UI5 element DatePicker

Hi,

I tried to migrate the UIVERI5 recording for sap.m.DatePicker UI5 element, and it seems that WDI5 is unable to handle it.

The error thrown is as follows:

[0-0] ERROR: call of _getControl() failed because of: Error: No DOM element found using the control selector {"id":"application-xxxxxxxxxx-component---xxxxxxx--startDateTimePicker-cal--Month0-20220113"}
[0-0] applicationxxxxxxxxxxcomponentxxxxxxxxxstartdatetimepickercalmonth020220113 has no sReplFunctionNames
[0-0] creating internal control with id applicationxxxxxxxxxxcomponentxxxxxxxxxstartdatetimepickercalmonth020220113 
[0-0] ERROR: call of _getControl() failed because of: Error: No DOM element found using the control selector {"id":"application-xxxxxxxxxx-component---xxxxxxx--startDateTimePicker-cal--Month0-20220113"}

The code

browser.asControl({
			selector: {
				id: "application-xxxxxxxxxx-component---xxxxxxx--startDateTimePicker-cal--Month0-20220113"
			},
			forceSelect: true
		}).getWebElement().click(); 

In the above code (after I have clicked on the DatePicker-icon-> I see a date picker popup), I select a date in the past.

Similarly the code for selection of month also fails.

 browser.asControl({
			selector: {
				id: "application-xxxxxxxxxx-component---xxxxxxx--startDateTimePicker-cal--MP-m0"
			},
			forceSelect: true
		}).getWebElement().click();

Initially I thought, it was a caching issue, and therefore used forceSelect : true.
However this did not work.

Thanks,
SN

accelerate $sap.m.List.getItems()

currently $control.getItems() returns a wdi5-object per list item in the sap.m.List's aggregation.
This doesn't scale for large aggregations.
Resolution ideas

  • parameter to $control.getItems() on wdi5/node-scope to retrieve item lenght only (e.g. $control.getItems(bCount)
  • separate count function $control.getItemsLength()
  • ...

Failed to find control with error "Error: waitAsync is already running and cannot be called again at this moment"

Hi Experts,

There's a strange error in my test. My test is very simple, after opening the page, there are two assertions: asserting control A is visible and asserting control B is visible.

If I only write any one of the assertions, the test will pass. But if both assertion exists (no matter what the sequence is), the first one will be success but the second will fail with error: "Error: waitAsync is already running and cannot be called again at this moment". Any idea on this? Thank you!

UI5 version: 1.97.1

Thank you and best regards,
Cong

How to check if an element does not exist?

Hi,

with WebdriverIO selectors we can check if a screen element does not exist at all:

await expect(await $('[id*=progressFilter]')).not.toExist();

When using the same with WDI5 selectors it doesn't work, as browser.asControl() throws a 'No DOM element found...' exception:

await expect(await (await browser.asControl(alertUI.master.progressFilter)).getWebElement()).not.toExist();

As a workaround i currently use a try-catch block around browser.asControl() and then assert against the exception.

Do you know any better way to check this? If not, are there any plans to support it in future?

forceSelect for Aggregations

The parameter forceSelect: true can be used to update the internally stored references; however, if the retrieved control is used to call aggregations (e.g. ListControl.getItems(), dialogContro.getButtons()), the resulting reference is always reused. forceSelect: true could be propagated to the aggregated controls to avoid errors due to an outdated reference.

Add cli option for save-screenshot=false

Running tests that include taking screenshots repeatedly (e.g. during debugging) results in unnecessarily high numbers of screenshots. Commenting out multiple screenshots in various files is a tedious task that might be automated using a cli parameter to skip all screenshot calls.

How to set the waitFor timeout ?

Hello, I am playing a bit with the tool to migrate some UIVeri5 scripts I own and I am facing an issue with a timeout that seems to be set to 15s (the default of OPA ?).
Can we increase the timeout globally or for a given browser.asControl call ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.