Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented DOM Node extensions mechanism (closes #749) #795

Merged

Conversation

kirovboris
Copy link
Collaborator

@testcafe-build-bot
Copy link
Collaborator

✅ Tests for the commit b15426e have passed. See details.

@inikulin
Copy link
Contributor

Wow, it was quick, but unfortunately not on time. We're on code freeze right now, so let's merge it after release, ok? Also, we have a new rule of adding/modifying basic example tests to demonstrate new feature. Can you add such example for find method (for extensions we'll have dedicated topic in docs about selector extensions)

@kirovboris
Copy link
Collaborator Author

let's merge it after release, ok?

Of course, I'll switch on the actual tasks now and will add an example later.

@VasilyStrelyaev
Copy link
Collaborator

lgtm, meanwhile

@testcafe-build-bot
Copy link
Collaborator

✅ Tests for the commit cc2f714 have passed. See details:

@kirovboris kirovboris changed the title Implemented DOM Node extensions mechanism, added 'find' method (closes #749) Implemented DOM Node extensions mechanism (closes #749) Nov 28, 2016
@testcafe-build-bot
Copy link
Collaborator

✅ Tests for the commit e1325a5 have passed. See details:

@kirovboris
Copy link
Collaborator Author

@inikulin @AlexanderMoskovkin
In according to the last API changes, i suggest the following usage of snapshot extensions:

const el1 = Selector('.my-class').extendSnapshot({
    prop1: node => ...
});

expect(await el1.prop1).eql(...); 

const el2 = el1.extendSnapshot({
    prop2: node => ...
})

expect(await el2.prop1).eql(...); 
expect(await el2.prop2).eql(...); 

I.e. we add .extendSnapshot method instead of .with({snapshotExtensions: {...} }) and provide possibility its hierarchical using.

@testcafe-build-bot
Copy link
Collaborator

❌ Tests for the commit 5e34753 have failed. See details:

@kirovboris
Copy link
Collaborator Author

@testcafe-build-bot \retest

@testcafe-build-bot
Copy link
Collaborator

❌ Tests for the commit 5e34753 have failed. See details:

@kirovboris
Copy link
Collaborator Author

@testcafe-build-bot \retest

@testcafe-build-bot
Copy link
Collaborator

❌ Tests for the commit 5e34753 have failed. See details:

@kirovboris kirovboris added this to the Sprint #3 milestone Dec 9, 2016
Copy link
Contributor

@inikulin inikulin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

\r-

}

function addSnapshotPropertyShorthands (obj, getSelector, snapshotExtensions) {
var properties = SNAPSHOT_PROPERTIES.concat(snapshotExtensions ? Object.keys(snapshotExtensions) : []);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it's better be rewritten as:

var properties = SNAPSHOT_PROPERTIES;

if (snapshotExtensions)
    properties = properties.concat(Object.keys(snapshotExtensions));

@@ -223,7 +237,17 @@ function addFilterMethods (obj, getSelector, SelectorBuilder) {
};
}

function createHierachicalSelector (getSelector, SelectorBuilder, selectorFn, filter, additionalDependencies) {
function addSnapshotExtensionMethods (obj, getSelector, SelectorBuilder) {
obj.extendSnapshot = extensions => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are getting rid of snapshot term in the first place. Maybe we'll rename it to addCustomDomProperty?

assertObject('extendSnapshot', '"extendSnapshot" option', extensions);

Object.keys(extensions).forEach(prop => {
assertFunction('extendSnapshot', `extendSnapshot '${prop.replace(/'/g, "\\'")}'`, extensions[prop]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we need to escape ' in property name here? Also I guess it's better to change text to Snapshot extensions method or smthg like that

@@ -40,6 +41,12 @@ export default class SelectorExecutor extends ClientFunctionExecutor {
}
}

_extendSnapshot (snapshot, node, extensions) {
Object.keys(extensions).forEach(prop => {
snapshot[prop] = extensions[prop](node);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to catch errors from extension methods and report them appropriately, e.g.:

`someProp` custom selector DOM property error:
[error text]

.getResult()
.then(result => {
var node = result;
var snapshot = this.replicator.encode(result)[0];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to pass extensions to replicator and appropriate transformers somehow. If you attach them afterwards, newly added properties will not be processed by replicator and thus circular references will throw errors and you will not be able to encode advanced data types. Also, note that selector can work in counter and collection modes: https://github.com/kirovboris/testcafe-phoenix/blob/5e34753e68f732c0ad639f9076c349330422014f/src/client/driver/command-executors/client-functions/selector-executor/filter.js#L101 First one used to calculate .exists and .count and the second one is used in chains. Make sure everything works correctly with extensions in this mode.

@kirovboris kirovboris removed this from the Sprint #3 milestone Dec 9, 2016
@testcafe-build-bot
Copy link
Collaborator

❌ Tests for the commit 5e34753 have failed. See details:

@testcafe-build-bot
Copy link
Collaborator

❌ Tests for the commit b63632c have failed. See details:

@kirovboris
Copy link
Collaborator Author

@testcafe-build-bot \retest

@testcafe-build-bot
Copy link
Collaborator

❌ Tests for the commit b63632c have failed. See details:

@kirovboris
Copy link
Collaborator Author

@testcafe-build-bot \retest

@testcafe-build-bot
Copy link
Collaborator

✅ Tests for the commit b63632c have passed. See details:

@kirovboris
Copy link
Collaborator Author

FPR

@VasilyStrelyaev
Copy link
Collaborator

As far as I understand your recent changes in the docs, we now use the term snapshot for an object that is explicitly awaited, When talking about DOM node properties accessed by using a selector in general, we say state.

Since custom properties can also be accessed through shorthands, we may need to rename the method to extendState or simply extend.

Does it make sense?

@kirovboris
Copy link
Collaborator Author

Yes, i agree, also extend is shorter for typing.

@@ -244,7 +262,17 @@ function addFilterMethods (obj, getSelector, SelectorBuilder) {
};
}

function addHierachicalSelectors (obj, getSelector, SelectorBuilder) {
function addCustomDomProperty (obj, getSelector, SelectorBuilder) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's wrong naming.

It should be what we are adding to selector object (as addFilterMethods). So, it should be like addExtendMethod.

Copy link
Contributor

@inikulin inikulin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

\r-

@@ -88,8 +90,23 @@ async function getSnapshot (getSelector, callsite) {
return node;
}

function addSnapshotPropertyShorthands (obj, getSelector) {
SNAPSHOT_PROPERTIES.forEach(prop => {
function assertSnapshotExtensionOptions (extensions) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've discussed it with @VasilyStrelyaev, he didn't see addCustomDOMProperties variant. Let's stick with it. Also, make sure that naming is consistent across codebase

@@ -78,6 +78,12 @@ export default {
${escapeHtml(err.errMsg)}
`),

[TYPE.uncaughtErrorInSnapshotExtensionCode]: err => markup(err, `
An error occurred when trying to calculate a custom ${err.property} property:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Custom property of what?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of selector? Don't think so. I have no other thoughts though. Custom DOM element state property?

@kirovboris, whose property is this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we write something like "... custom Selector property <prop>"?
@inikulin

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new FunctionTransform()
]);
//Overridable methods
_addReplicatorTransform () {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to extract methods this way for replicator, just keep it as is. In selector constructor just create SelectorTransform and add it to replicator manually.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understood your comment. If I add ClientFunctionTransform in constructor of the base class ClientFunctionExecutor, I can't add SelectorTransform in SelectorExecutor constructor, because we can't add two transforms with the same type Node to the replicator.

prop2: node => 'tagName: ' + node.tagName
});

expect(await el.prop1).eql(42);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use built-in assertons

@kirovboris kirovboris force-pushed the extending_node_snapshot branch 2 times, most recently from ed40d0c to 541d615 Compare January 9, 2017 11:30
@testcafe-build-bot
Copy link
Collaborator

✅ Tests for the commit 541d615 have passed. See details:

@kirovboris
Copy link
Collaborator Author

FPR, we've discussed with @VasilyStrelyaev the name of method and decided to keep .addCustomDOMProperties()

Copy link
Contributor

@inikulin inikulin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, lgtm. Just some minor issues left. Also, would you mind adding feature summary?

this.type = 'Node';
constructor (customDOMProperties) {
this.type = 'Node';
this.customDOMProperties = customDOMProperties || {};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Formatting issue, assignments should be aligned

@@ -78,6 +78,12 @@ export default {
${escapeHtml(err.errMsg)}
`),

[TYPE.uncaughtErrorInCustomDOMPropertyCode]: err => markup(err, `
An error occurred when trying to calculate a custom Selector property ${err.property}:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

custom Selector DOM property? I guess it's worth enclosing property name into quotes: "${err.property}"

@@ -59,6 +59,13 @@ export function assertNonNullObject (callsiteName, what, value) {
}
}

export function assertFunction (callsiteName, what, value) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be implemented already, try to rebase onto latest changes

@kirovboris
Copy link
Collaborator Author

kirovboris commented Jan 10, 2017

So, we can extend a snapshot / Selector the following way:

//Add the new property 'contentEditable' to the Selector
const el = Selector('.my-el').addCustomDOMProperties({
    contentEditable: node => node.contentEditable
});

//Now, we can use it as shorthand property 
await t.expect(await el.contentEditable).eql(...);

//Or as a snapshot's property
const snapshot = await el();

await t.expect(await snapshot.contentEditable).eql(...);

//Also we can extend / override custom properties
el = el.addCustomDOMProperties({
    contentEditable: node => /*some_new_logic*/,
    tabIndex: node => node.tabIndex
});

@kirovboris
Copy link
Collaborator Author

@testcafe-build-bot \retest

@testcafe-build-bot
Copy link
Collaborator

❌ Tests for the commit 53d31bb have failed. See details:

@kirovboris
Copy link
Collaborator Author

@testcafe-build-bot \retest

@testcafe-build-bot
Copy link
Collaborator

✅ Tests for the commit 53d31bb have passed. See details:

@kirovboris
Copy link
Collaborator Author

FPR

@testcafe-build-bot
Copy link
Collaborator

❌ Tests for the commit 04bd388 have failed. See details:

@kirovboris
Copy link
Collaborator Author

@testcafe-build-bot \retest

@testcafe-build-bot
Copy link
Collaborator

✅ Tests for the commit 04bd388 have passed. See details:

@kirovboris
Copy link
Collaborator Author

FPR

Copy link
Contributor

@inikulin inikulin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@AlexanderMoskovkin AlexanderMoskovkin merged commit 7d9da93 into DevExpress:master Jan 11, 2017
kirovboris added a commit to kirovboris/testcafe-phoenix that referenced this pull request Dec 18, 2019
…vExpress#795)

* Implemented DOM Node extensions mechanism (closes DevExpress#749)

* Fixed remarks

* Renamed extendSnapshot method

* Fixed remark

* Fixed remarks

* Fixed remarks

* Added the possibility of extending non ElementNode snapshots
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants