Cypress 12 + angular 15 + input chain failling randomly - angular-material

I just migrate my application from angular 12 to angular 15 (and material 15).
The cypress also migrated from 8.7.0 to 12.3.0
Since the migration, the existing cypress tests are not constant in execution.
I have too kinds of issue:
Cannot get element by id or css class. The error is “…is being covered by another element“
Synchronisation is not perfect on input chaining. As example :
cy.get('#birthPlace_id') .clear() .type('London') .should('have.class', 'ng-valid');
In this test code execution, the type starts meanwhile the clear instruction is not completely finished. This give a wrong input value with a mix of previous and new typed values.
Here is my configuration:
`
defaultCommandTimeout: 60000,
execTimeout: 60000,
pageLoadTimeout: 60000,
requestTimeout: 60000,
responseTimeout: 60000,
taskTimeout: 60000,
videoUploadOnPasses: true,
screenshotOnRunFailure: false,
videoCompression: false,
numTestsKeptInMemory: 0,
animationDistanceThreshold: 20,
waitForAnimations: false,
env: { 'NO_COLOR': '1' },
retries: {
runMode: 4,
openMode: 0
},
fileServerFolder: '.,',
modifyObstructiveCode: false,
video: false,
chromeWebSecurity: true,
component: {
devServer: {
framework: 'angular',
bundler: 'webpack'
}
}
`
I already tried to:
Add “force: true”
Add a wait(1000) or another value
Use click() method before
I increased the timeout in the config file for all
But same comportment randomly it can also work perfectly, but major time not at all.
I would expect that the call to clear(), type(), should() are perfectly synchronised and does not start before the previous one is not finished yet.
My question: is there a better way to do chaining ? Does something change since Cypress 8 to chain instruction on element ?

In this test code execution, the type starts meanwhile the clear instruction is not completely finished.
You can guard against this by adding an assertion after .clear().
This retries the test flow until the control has been cleared.
cy.get('#birthPlace_id')
.clear()
.should('have.value', '')
.type('London')
.should('have.value', 'London')

Related

Twilio Flex Voicemail Flex Task Assignment Workflow

Hello I have a workflow here
It sends callers to a queue with a single worker.
I want to implement voicemail and have followed the instructions here https://support.twilio.com/hc/en-us/articles/360021082934-Implementing-Voicemail-with-Twilio-Flex-TaskRouter-and-Insights
If I put the filter first in the workflow then it always goes to voicemail, if next then it never goes.
How can I make it so that if calls are maybe reserved but not answered they go to the voicemail queue?
{
"task_routing": {
"filters": [
{
"filter_friendly_name": "Voicemail ",
"expression": "1==1",
"targets": [
{
"queue": "theRealqueue",
"timeout": 10
},
{
"queue": "voicemail",
"timeout": 10
}
]
}
],
"default_filter": {
"queue": "gfhfghgfhghfghgfhfghgfh"
}
}
}
I believe that the timeout you have set for each of the targets counts as the time the task spends in that queue regardless of the target. In the case of the workflow you shared, when a task spends 10 seconds in theRealqueue and then times out, it also times out of the voicemail queue because that was also 10 seconds.
Try setting the voicemail queue target to a bigger timeout than theRealqueue.
"targets": [
{
"queue": "theRealqueue",
"timeout": 10
},
{
"queue": "voicemail",
"timeout": 20
}
]
There were 3 problems.
I decided to put in a,
"skip_if": "workers.available == 0" On the first filter and it makes sense now as in the GUI, it is DO NOT SKIP as the default, so to my thinking that means what it says.
And WOW it worked, I had earlier set a TASK RESERVATION TIMEOUT of 8 seconds but when I tried increasing this it never got to voicemail/never went to next step.
I could only get it to work with that 8 second TASK RESERVATION TIMEOUT, not a larger value so then I looked in the Studio Flow,
SEND TO FLEX had a timeout of 10 second, my bad. Increased and all good now.
The documentation/tutorial here is terrible, https://support.twilio.com/hc/en-us/articles/360021082934-Implementing-Voicemail-with-Twilio-Flex-TaskRouter-and-Insights
Select the default Assign to Anyone workflow, or the appropriate workflow if you have modified this.
Click Add a Filter.
Name your Filter Voicemail (or something similarly identifiable), and then change the TIMEOUT to 30 seconds. Click Add a Step when finished.
Click the QUEUE value, and then select the Voicemail queue you created in the previous section. Press Save when finished.
That is all not so relevant here, it seems that the thing that controls the going to next step is the TASK RESERVATION TIMEOUT and that no step would be skipped/passed unless a "skip_if": is defined.
I would really love to get clarification on all this.
But the steps that I have done have provided a solution. I banged my head into walls for a few days here.

LCP result is totally opposite from performance API than the pagespeed insights or webpagetest

I am trying to optimise LCP for this page. I read an article on LCP optimisation where I also found a script which can help to determine which part of the LCP most time is spent on. Script:
const LCP_SUB_PARTS = [
'Time to first byte',
'Resource load delay',
'Resource load time',
'Element render delay',
];
new PerformanceObserver((list) => {
const lcpEntry = list.getEntries().at(-1);
const navEntry = performance.getEntriesByType('navigation')[0];
const lcpResEntry = performance
.getEntriesByType('resource')
.filter((e) => e.name === lcpEntry.url)[0];
// Ignore LCP entries that aren't images to reduce DevTools noise.
// Comment this line out if you want to include text entries.
if (!lcpEntry.url) return;
// Compute the start and end times of each LCP sub-part.
// WARNING! If your LCP resource is loaded cross-origin, make sure to add
// the `Timing-Allow-Origin` (TAO) header to get the most accurate results.
const ttfb = navEntry.responseStart;
const lcpRequestStart = Math.max(
ttfb,
// Prefer `requestStart` (if TOA is set), otherwise use `startTime`.
lcpResEntry ? lcpResEntry.requestStart || lcpResEntry.startTime : 0
);
const lcpResponseEnd = Math.max(
lcpRequestStart,
lcpResEntry ? lcpResEntry.responseEnd : 0
);
const lcpRenderTime = Math.max(
lcpResponseEnd,
// Prefer `renderTime` (if TOA is set), otherwise use `loadTime`.
lcpEntry ? lcpEntry.renderTime || lcpEntry.loadTime : 0
);
// Clear previous measures before making new ones.
// Note: due to a bug this does not work in Chrome DevTools.
// LCP_SUB_PARTS.forEach(performance.clearMeasures);
// Create measures for each LCP sub-part for easier
// visualization in the Chrome DevTools Performance panel.
const lcpSubPartMeasures = [
performance.measure(LCP_SUB_PARTS[0], {
start: 0,
end: ttfb,
}),
performance.measure(LCP_SUB_PARTS[1], {
start: ttfb,
end: lcpRequestStart,
}),
performance.measure(LCP_SUB_PARTS[2], {
start: lcpRequestStart,
end: lcpResponseEnd,
}),
performance.measure(LCP_SUB_PARTS[3], {
start: lcpResponseEnd,
end: lcpRenderTime,
}),
];
// Log helpful debug information to the console.
console.log('LCP value: ', lcpRenderTime);
console.log('LCP element: ', lcpEntry.element);
console.table(
lcpSubPartMeasures.map((measure) => ({
'LCP sub-part': measure.name,
'Time (ms)': measure.duration,
'% of LCP': `${
Math.round((1000 * measure.duration) / lcpRenderTime) / 10
}%`,
}))
);
}).observe({type: 'largest-contentful-paint', buffered: true});
For me, this was the result at the start in 4x CPU slowdown and Fast3G connection.
After that, since render delay was the area where I should focus on, I moved some of the scripts to the footer and also made the "deferred" scripts "async". This is the result:
We can see there is a clear improvement in LCP after the change but, when I test with lighthouse the result is different.
Before:
After:
I am in dilemma now about what step to take. Please suggest!!
I ran a trace of the URL you linked in your question, and the first thing I noticed is that your LCP resource finishes loading pretty early in the page, but it isn't able to render until a file called mirage2.min.js finishes loading.
This explains why your "Element render delay" portion of LCP is so long, and moving your scripts to the bottom of the page or seeing defer of them is not going to solve that problem. The solution is to make it so your LCP image can render without needing to wait until that JavaScript file finishes loading.
Another thing I noticed is this mirage2.min.js file is loaded from ajax.cloudflare.com, which made me think it's a "feature" offered by Cloudflare and not something you set up yourself.
Based on what I see here, I'm assuming that's true:
https://support.cloudflare.com/hc/en-us/articles/219178057
So my recommendation for you is to turn off this feature, because it's clearly not helping your LCP, as you can see in this trace:
There's one more thing you said that I think is worth clarifying:
After that, since render delay was the area where I should focus on, I moved some of the scripts to the footer and also made the "deferred" scripts "async". This is the result:
When I look at your "result" screenshot, I still see that the "element render delay" portion is still > 50%, so while you were correct when you said that "render delay was the area where I should focus on", the fact that it was still high after you made your changes (e.g. moving the scripts and using defer/async) was an indication that the changes you tried didn't fix the problem.
In this case, I believe that if you turn off the "Mirage" feature in your Cloudflare dashboard, you should see a big improvement.
Oh, one more thing, I noticed that you're using importance="high" on your image. This is old syntax that does not work anymore. You should replace that with fetchpriority="high" instead. See this post for details: https://web.dev/priority-hints/

ng-block-ui not working with Angular 7 concatmap

I'm using NgBlockUI and BlockUIHttpModule with blockAllRequestsInProgress set to true in an app I'm working on. In general it's working fine, but on one page I'm using a concat map to perform some action and then update the data. The first request, the update, triggers BlockUI fine, but the second one doesn't. Otherwise, it executes properly. It's just a little jarring for the user since the results seem to update without warning. Here's the code for the function:
onUpdate(event: items[]) {
this.updateService.update(event).concatMap(
_ => this.seachService.search(this.cachedSearch)
).subscribe(
resp => this.handleResponse(resp),
err => this.handleError(err)
);
}
I tried calling BlockUI directly, but still no luck. As a last resort, I'm going to make the whole thing one request, but I'd like to at least understand why this isn't working.
This happened to me as well. This issue occurs for sequential HTTP calls (usually with await) wherein the second request is not blocked by ng-block-ui.
As fix what I did was set blockAllRequestsInProgress to false. The behavior is just the same but setting it to false yields more predictable results:
BlockUIHttpModule.forRoot({
blockAllRequestsInProgress: false,
requestFilters: [urlFilter]
}),
I've also updated to ng-block-ui to latest version as of this writing:
"ng-block-ui": "^2.1.8",

Expect: does not get the actual value

I faced with very strange problem. I had a set of tests which I run daily on Jenkins and without any noticeable changes some asserts(expects) started fail. THe strange thing here is that they fails ONLY if I execute tests from Jenkins on Browserstack. Locally everything just fine, locally on browserstack everything is fine, on saucelabs everything is fine. I have 3 it() blocks with similar expects:
value1 = $('.someclass');
value2 = ..
value3 = ..
expect(value1.getText()).toContain('tratata');
expect(value2.getText()).toContain('uhuhuhu');
expect(value3.getText()).toContain('ahahaha');
they are all situated in different it() blocks. Now strange thing:
When I execute tests, test with 1st assert block passes just fine, on the 2nd it block it says that assert fails(i do some stuff in order to change values), but manually / locally I see that everything is fine. Also while test is getting executed I see that values are getting changed ( i even did screenshots and check visual log on browserstack). In the 3rd it block I did other action and assert fails again, BUT it compare it with value which I was expected from step 2, not step 1!! SO looks like for some reason I am one step behind... If I comment it block or just asserts in the 1st test, 2nd one passes fine, but 3 fails. If I comment 2 it block, 3rd passes fine.
Sounds like that in this particular case for some reason some magic happens and only on Jenkins and only on Browserstack. By the way tests have been working for a while without any problems and started fail without any updates.
I though that for some reason I have problems with control flow, I WAIT for elements to be presented in addition, I tried browser.sleep() anti-pattern also to investigate it better, but it magically keeps be on the step behind.
I am not looking for particular solution directly, but any suggestions will be highly appreciated, I am not sure which additional info I should provide, hope I described the problem enough.
#protractor2.1.0
#jasmine2.3.2
browser.ignoreSynchronization = false
it('', function () {
expect(viewBookingDetailsPage.totalCostSection.depositDue.getText()).toContain('542.00');
expect(viewBookingDetailsPage.totalCostSection.remainingBalance.getText()).toContain('4,878.00');
expect(viewBookingDetailsPage.totalCostSection.totalDepositAmount.getText()).toContain('5,420.00');
});
it('', function () {
$(viewBookingDetailsPage.eventAndItemsSection.addItemsBtn).click();
helper.waitElementToBeVisisble(viewBookingDetailsPage.addItemsModal.modalOpen);
viewBookingDetailsPage.addonItemAttribute(0, viewBookingDetailsPage.addItemsModal.events).click();
helper.waitElementToBeVisisble(viewBookingDetailsPage.addItemsModal.eventSelectionPopup);
viewBookingDetailsPage.addItemsModal.availableEvents.then(function (events) {
//Morning event
events[3].$('i').click();
viewBookingDetailsPage.addonItemAttribute(0, viewBookingDetailsPage.addItemsModal.selectItem).click();
viewBookingDetailsPage.addonItemAttribute(1, viewBookingDetailsPage.addItemsModal.selectItem).click();
viewBookingDetailsPage.addItemsModal.addButton.click();
helper.waitElementToDisappear(viewBookingDetailsPage.addItemsModal.modalOpen);
helper.waitElementToBeVisible(viewBookingDetailsPage.addonItemDetail(0, 0, 0, viewBookingDetailsPage.eventAndItemsSection.itemName));
expect(viewBookingDetailsPage.totalCostSection.depositDue.getText()).toContain('592.00');
expect(viewBookingDetailsPage.totalCostSection.remainingBalance.getText()).toContain('5,328.00');
expect(viewBookingDetailsPage.totalCostSection.totalDepositAmount.getText()).toContain('5,920.00');
});
});
it('', function () {
viewBookingDetailsPage.addonItemDetail(0, 0, 0, viewBookingDetailsPage.eventAndItemsSection.removeItem).click(); ----- method just returns element into multiple internal repeaters
expect(viewBookingDetailsPage.totalCostSection.depositDue.getText()).toContain('580.00');
expect(viewBookingDetailsPage.totalCostSection.remainingBalance.getText()).toContain('5,220.00');
expect(viewBookingDetailsPage.totalCostSection.totalDepositAmount.getText()).toContain('5,800.00');
});
I fixed this with waiting directly to text to change:
browser.wait(function() {
return viewBookingDetailsPage.totalCostSection.depositDue.getText().then(function(text) {
return text === '592.00USD';
});
}, 15000);
I am sure that something goes wrong here, but it worked for me. If I will have some free time I will try to enhance the answer and investigate it deeper.
This post hints at the fact that one of the steps could be blocked waiting to complete: http://makandracards.com/makandra/1709-single-step-and-slow-motion-for-cucumber-scenarios-using-javascript-selenium. Not sure if that helps at all.

PhantomJs timeout

I am using Jasmine with PhantomJS to run test cases.
In my typical test case, I make a service call, wait for response and confirm response.
Some requests can return in a few seconds and some can take up to a minute to return.
When ran through PhantomJS, the test case fails for the service call that is supposed to take a minute ( fails because the response is not yet received).
What's interesting is that the test passes when ran through Firefox.
I have tried looking at tcpdump and the headers are same for requests through both browsers, so this looks like a browser timeout issue.
Has anyone had a similar issue ? Any ideas as to where could the timeout be configured ? Or do you think the problem is something else ?
Ah the pain of PhantomJS.
Apparently it turned out that I was using javascript's bind function which is not supported in PhantomJS .
This was causing the test to fail which resulted in messing up state of some global variable( my fault) and hence the failure.
But the root cause was using bind.
Solution: try getting a shim for bind like this from https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== "function") {
// closest thing possible to the ECMAScript 5 internal IsCallable function
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function () {},
fBound = function () {
return fToBind.apply(this instanceof fNOP && oThis
? this
: oThis,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}
I had exactly same issue. All you have to do is add setTimeout to exit
setTimeout(function() {phantom.exit();},20000); // stop after 20 sec ( add this before you request your webpage )
page.open('your url here', function (status) {
// operations here
});

Resources