-
Notifications
You must be signed in to change notification settings - Fork 308
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
Remove more internal angular attributes from snapshots #336
Comments
I would like to ask you to add these to the |
Just to keep track: __ngContext__={[Function LRootView]} |
Woof, I wish I would have ran into this an hour ago. I ended up creating this, but I'm going to pull in what you have since it's more comprehensive const classRegexes = [/^ng-tns-.+$/, /ng-star-inserted/];
module.exports = {
print: (node: HTMLElement, serialize: (node: Node) => string) => {
const clone = node.cloneNode(true) as HTMLElement;
const matchingClasses = Array.from(clone.classList).filter((c) => classRegexes.some((r) => r.test(c)));
clone.classList.remove(...matchingClasses);
return serialize(clone);
},
test: (node: HTMLElement) => {
const classes = Array.from(node.classList ?? []);
return classes.some((c) => classRegexes.some((r) => r.test(c)));
},
}; |
PRs to enhance the currently included serializer are welcome! |
@wtho - after I posted my last note I realized it wasn't working quite the way I wanted it to: there were still nodes that contained the values I wanted to strip. It looks like the issue is coming from the other serializers: by using 'serialize' opposed to 'print' it seems like some nodes don't end up making it further down the pipeline. I reordered my serializers so that this one comes first: snapshotSerializers: [
'./jest/ng-id-stripper.serializer.ts',
'jest-preset-angular/build/AngularNoNgAttributesSnapshotSerializer.js',
'jest-preset-angular/build/AngularSnapshotSerializer.js',
'jest-preset-angular/build/HTMLCommentSerializer.js',
], And updated my prior version to use print opposed to serialize: const attributesToClean: { [key: string]: RegExp[] } = {
class: [/^ng-tns-.+$/, /^ng-star-inserted$/], // e.g. "ng-tns-c25-1", "ng-star-inserted"
id: [/^.*-\d+$/, /^root\d+$/], // e.g. "mat-input-4", "cdk-step-content-0-0", "root0"
for: [/^.*-\d+$/], // e.g. "mat-form-field-label-9"
'aria-owns': [/^.*-\d+$/], // e.g. "mat-input-4"
'aria-labelledby': [/^.*-\d+$/], // e.g. "mat-input-4", "cdk-step-label-0-0"
'aria-controls': [/^.*-\d+$/], // e.g. "cdk-step-content-2-0"
};
const attributesToCleanKeys = Object.keys(attributesToClean);
const hasAttributesToClean = (attribute: Attr) => attributesToCleanKeys.some((name) => attribute.name === name);
let lastCleanedNode: Element | null = null;
module.exports = {
print: (val: Element, serialize: (v: Element) => string) => {
const clone = val.cloneNode(true) as Element;
for (const attr of Object.values(clone.attributes).filter(hasAttributesToClean)) {
attr.value = attr.value
.split(' ')
.filter((attrValue: string) => {
return !attributesToClean[attr.name].some((regex) => regex.test(attrValue));
})
.join(' ');
}
lastCleanedNode = clone;
return serialize(clone);
},
test: (val: Element) => val !== lastCleanedNode && val.attributes !== undefined && Object.values(val.attributes).some(hasAttributesToClean),
}; Going this route I was also able to add in that At this point I think it's doing what I need it to do, but still a WIP: Opposed to just testing the node to see if it's the one we just cleaned, a better solution may be to have the test actually check to see if there's something to remove, but that would be a less efficient solution I think |
I'm wondering, is it an issue that gone with 8.4.0 and nobody has it, or it's still there and more PRs should be created for it? Indeed with Ivy snapshots have unexpected output, watch mode/cache param could show and hide |
The current serializer is still open for improvement :) feel free to submit a PR |
Interesting that without --watch mode, Update: |
in my case the diff is not only about ngContext there are blank spaces are added as well. but the trigger is not about --watch but diff env: ci/local haven't had time to go deep😉 |
@yherasymchukarchitech @pillsilly Would be great if you manage to create a simple reproduction and open a new issue so we can investigate and fix this problem with you. |
@pillsilly assuming you mean you're seeing inconsistency in the screenshots, one issue we ran into earlier is you need to make sure the environments are consistent from an ivy compilation standpoint. Locally everything's probably compiled, but that might not be the case in the CI: you may want to make sure you run |
thank you guys, but now my problem if that I want to reproduce the snapshot (I mean generate snapshot without ngcc being done) |
Since Angular 14 |
I still have problems. When i run all my test at once, the snapshot has |
Ok, the problem is still not solved... Does anyone have an idea how to fix this? |
Does this exist in a repo or a gist somewhere, I'm trying to fight the root0, root1 problem in angular snapshots and the angular preset serializers appear to do nothing, or nothing for this problem. Also what's the license on this code |
Currently, snapshots often contain internal angular attribute values that cause tests to fail.
PR #97 fixed some of these but there are still more. The remaining ones were discussed in that PR but were shelved at that time. This new issue tracks the need to continue where that PR left off and remove the additional attribute + attribute values.
This issue is especially problematic when working with Angular Material. The snapshots will often contain one of the following attribute+values where the numeric indexes change.
class=ng-tns-c25-1
aria-owns=mat-input-4
aria-labelledby=mat-input-4
aria-controls=cdk-step-content-2-0
id=cdk-step-content-0-0
for=mat-form-field-label-9
Interestingly, the snapshots don't error on repeated executions of the same tests since the numeric indexes remain constant. However, if you rearrange the order of the same tests or add new tests before existing tests, the indexes change and snapshots fail. It appears Angular globally stores an index counter (called a
namespaceId
) and sequentially increments them for each render. If we had a way to reset this global state before each test, then this issue wouldn't be a problem since the indexes would be consistent. I was not able to find a way to do this albeit multiple attempts.A quick workaround is to add a local Serializer and reference it in
snapshotSerializers
. Source code below:AngularStripAnimationAttributesSnapshotSerializer.ts
The text was updated successfully, but these errors were encountered: