ember-cli-page-object icon indicating copy to clipboard operation
ember-cli-page-object copied to clipboard

Custom properties

Open yratanov opened this issue 5 years ago • 8 comments

Hi,

I am using Ember 3.3 + "ember-cli-page-object": "^1.15.2".

I'm trying to add new property to be used in page object like this:

// page 

export default create({
  role: powerSelect('.role'),
  submit: clickOnText('.btn'),
});

// powerSelect property defined like this

export function powerSelect(selector) {
  return {
    isDescriptor: true,

    get(_) {
      return function(text) {
        wait().then(() => {
          selectChoose(selector, text);
        });

        return this;
      };
    }
  };
}

//test 
module('Some module', function(hooks) {
  setupApplicationTest(hooks);

  test('adding priority', async assert => {
    await visit('/');
    await page.role('Admin');
    await page.submit();
  });
});

But it doesn't work properly. selectChoose does not finish, while submit is already clicked.

I looked in the code and it seems that my helper return value should be wrapped in runAsync from rfs268.js, but it is a private api....

So in genearal I have these questions:

  1. Why creation of new properties is not covered in the docs? Is it an unexpeted usage of the library?
  2. Why runAsync for all contexts is private?
  3. If I suppose to be able to write custom properties with interactions, how should I do it?

yratanov avatar Apr 10 '19 12:04 yratanov

@yratanov you could this without defining a property

export default create({
  role: powerSelect('.role'),
  submit: clickOnText('.btn'),
});

function powerSelect(selector) {
  return function(text) {
    selectChoose(selector, text);
  });
}

If you are still feeling strong about using a property, I would import getExecutionContext, I know it's private, but we should move it to the public space so building properties is easier.

juanazam avatar Apr 10 '19 13:04 juanazam

@juanazam But it will break chaining, isn't it?

yratanov avatar Apr 10 '19 13:04 yratanov

As shown it will, but:

export default create({
  role: powerSelect('.role'),
  submit: clickOnText('.btn'),
});

function powerSelect(selector) {
  return function(text) {
    selectChoose(selector, text);
    return this;
  });
}

And using async await properly, it shouldn't.

juanazam avatar Apr 10 '19 13:04 juanazam

@juanazam not sure what you mean by "properly". I tried as you showed in your example, and it doesn't wait.

yratanov avatar Apr 10 '19 13:04 yratanov

@yratanov I don't have time to do it right now and test, but I'm pretty sure it's doable using await on the selectChoose helper.

juanazam avatar Apr 10 '19 14:04 juanazam

@juanazam

OK, so here what helped:

import { getExecutionContext } from 'ember-cli-page-object/-private/execution_context';

export function powerSelect(selector) {
  return {
    isDescriptor: true,

    get(_) {
      return function(text) {
        let executionContext = getExecutionContext(this);
        return executionContext.runAsync(() => {
          return selectChoose(selector, text);
        });
      };
    }
  };
}

I think it would be very nice to expose runAsync function to public scope.

yratanov avatar Apr 11 '19 07:04 yratanov

@yratanov totally agree! We miss a recommended way to define custom actions.

The problem with runAsync is that it's dependendent on -private/execution_context. Also there there are some things to be implemented to make actions creation easy. I have several WIP private branches which are supposed to address these points, hope to share them next week.

You can see a very initial piece of the effort at https://github.com/san650/ember-cli-page-object/pull/447, but this PR is incomplete and it's going to be extended soon.

ro0gr avatar Apr 11 '19 19:04 ro0gr

@yratanov that's perfect.

@ro0gr sounds great. Exposing internals for creating custom properties is definitely necessary.

juanazam avatar Apr 11 '19 19:04 juanazam