ui5-community / wdi5

official UI5 end-to-end test framework for UI5 web-apps. wdi5 = Webdriver.IO + UI5 Test API
https://ui5-community.github.io/wdi5/
Apache License 2.0
102 stars 43 forks source link

javascript error: Cannot read properties of undefined (reading 'waitForUI5Options') #323

Closed marco-paciucci closed 2 years ago

marco-paciucci commented 2 years ago

Hello, I have this piece of code in my test.js:

const { wdi5 } = require("wdio-ui5-service");

describe("My First Sample", function () {

    it('Step1: should load the app',async()=> {
        await browser.url("http://localhost:8080/index.html");
        browser.debug(); 
        await expect(browser).toHaveTitle("OpenUI5 Todo App");
    });

  it("Step2: should display the todo list",async()=> {

      const oSelector = {
         selector: {
                controlType: "sap.m.CheckBox",
                viewName: "sap.ui.demo.todo.view.App",
                bindingPath: {path: "/todos/1"}
         }
      }  
      const control = await browser.asControl(oSelector);
      button.click();
    });

  it("Step3: should have two items in the list",async()=> {
     const selector = {
         selector: {
                controlType: "sap.m.CustomListItem",
                viewName: "sap.ui.demo.todo.view.App" 
         }
      } 
      const control = await browser.asControl(selector);
      expect(control.count().toBe(2));

    });

  });

which returns:

[chrome 104.0.5112.81 windows #0-0] javascript error: Cannot read properties of undefined (reading 'waitForUI5Options') JavaScript stack: TypeError: Cannot read properties of undefined (reading 'waitForUI5Options') at eval (eval at executeAsyncScript (:552:26), :4:65) at eval (eval at executeAsyncScript (:552:26), :33:8) at eval (eval at executeAsyncScript (:552:26), :33:33) at executeAsyncScript (:552:47) at apply.selector.bindingPath.path (:567:29) at callFunction (:446:22) at :460:23 at :461:3 (Session info: chrome=104.0.5112.81)

The file wdio.conf.js contains this configuration:

    wdi5: {
        screenshotPath: "webapp/test/__screenshots__",
        screenshotsDisabled: false, // [optional] {boolean}, default: false; if set to true, screenshots won't be taken and not written to file system
        logLevel: "verbose", // [optional] error | verbose | silent, default: "error"
        url: "index.html", // [mandatory] {string} name of your bootstrap html file. If your server autoredirects to a 'domain:port/'-like root url, use empty string ''
        skipInjectUI5OnStart: false, // [optional] {boolean}, default: false; true when UI5 is not on the start page, you need to later call <wdioUI5service>.injectUI5() manually
        waitForUI5Timeout: 15000 // [optional] {number}, default: 15000; maximum waiting time in milliseconds while checking for UI5 availability
    },

And package.json

{
    "name": "openui5-sample-app",
    "version": "0.2.0",
    "description": "Sample of an OpenUI5 app",
    "private": true,
    "scripts": {
        "start": "ui5 serve",
        "lint": "eslint webapp",
        "karma": "karma start",
        "karma-ci": "rimraf coverage && karma start karma-ci.conf.js",
        "watch": "npm run karma",
        "test": "npm run lint && npm run karma-ci",
        "build": "ui5 build -a --clean-dest",
        "build-self-contained": "ui5 build self-contained -a --clean-dest",
        "serve-dist": "ws --compress -d dist",
        "wdi5": "wdio run wdio.conf.js"
    },
    "devDependencies": {
        "@ui5/cli": "^2.14.10",
        "@wdio/cli": "^7.20.9",
        "@wdio/local-runner": "^7.20.9",
        "@wdio/mocha-framework": "^7.20.7",
        "@wdio/spec-reporter": "^7.20.8",
        "chromedriver": "^104.0.0",
        "eslint": "^7.32.0",
        "karma": "^6.4.0",
        "karma-chrome-launcher": "^3.1.1",
        "karma-coverage": "^2.2.0",
        "karma-ui5": "^2.4.0",
        "local-web-server": "^4.2.1",
        "rimraf": "^3.0.2",
        "wdio-chromedriver-service": "^7.3.2",
        "wdio-ui5-service": "^0.9.10"
    }
}

Why am I getting this issue?

vobu commented 2 years ago

have you specified the "ui5" service in wdio.conf.js? https://ui5-community.github.io/wdi5/#/installation?id=c-manual-installation

also, you'll need to await the button click in your test "Step2: should display the todo list": await button.click()

marco-paciucci commented 2 years ago

Hello, nope await button.click() is not a valid SAP UI5 statement and clickmethod doesn't exist. Anyway there's something that doesn't tally up.

 const selector = {
     selector: {
            controlType: "sap.m.List",
            viewName: "sap.ui.demo.todo.view.App" 
     }
  } 
  const oControl = await browser.asControl(selector);
  const oModel = await oControl.getModel();
  wdi5.getLogger("MYLOG....Data of the model is ").log(oModel);
  const aTodos = await oModel.getProperty("/todos");
  const count = await aTodos.filter( el=>{if (el.completed) return 1; else return 0;}).length;
  wdi5.getLogger("MYLOG....The number of completed items is ").log(count);

The javascript code is perfectly fine and it works okay on the server However npm run wdi5 returns an error: oModel.getProperty is not a function and I cannot seem to figure out how to get it sorted.

vobu commented 2 years ago

nope await button.click() is not a valid SAP UI5 statement and clickmethod doesn't exist

that's correct, should have been await button.press()

const oModel = await oControl.getModel() const aTodos = await oModel.getProperty("/todos")

getModel() returns a complex object - so far, atomic values and UI5 controls are working in wdi5, but not complex objects. We're working on that in #252.

Glancing at your source and guessing for the rest: for your use case, getting all list items, then iterating them for the property checked (or similar), might be an alternative solution, à la (attention, untested code ahead)

const checkedItems = await browser.asControl(listSelector).getItems()
const checked = 0
for (const item of checkedItems) {
  if (await item.getChecked()) { checked++ }
}
expect(checked).toBe(2)

anyway, this issue now doesn't seem to be related to your original issue with cannot read properties..., or is it?

marco-paciucci commented 2 years ago

The original issue is gone and I will close this. It was due to the version of npm which was wrong and the installation wasn't completed successfully. I will then raise a separate issue for this code. Thank you