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

Fix flaky test by verifying that a search has been saved by checking for a success toast #21302

Closed
wants to merge 32 commits into from

Conversation

cjcenizal
Copy link
Contributor

@cjcenizal cjcenizal commented Jul 26, 2018

Fixes #20810 and #19750 by asserting that the search has saved by checking for the presence of a success toast. The flaky test then passed locally for me.

return await testSubjects.exists('saveDashboardSuccess');
// Confirm that the Dashboard has been saved and close the toast.
await testSubjects.existOrFail('saveDashboardSuccess');
await find.clickByCssSelector('[data-test-subj="saveDashboardSuccess"] [data-test-subj="toastCloseButton"]');
Copy link
Contributor

Choose a reason for hiding this comment

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

Does using await testSubjects.click('saveDashboardSuccess toastCloseButton'); work? I see that style used somewhere else.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good call, according to the tests for the test subj package, that should work.


// Make sure toast exists and then close it.
await testSubjects.existOrFail('saveSearchSuccess');
await find.clickByCssSelector('[data-test-subj="saveSearchSuccess"] [data-test-subj="toastCloseButton"]');
Copy link
Contributor

Choose a reason for hiding this comment

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

All of the testSubjects.existOrFails are unnecessary because the find will fail if it doesn't find toast. Or do you prefer keeping them in for readability? Only concern is that they do disappear after awhile. I don't think it will cause issues but it would stink if it passed the first call, then failed on the second because in the interim, the toast disappeared. Unless we could do what we did with the old style toasts and modify them so they never disappear. Or maybe we have that? I'm not sure if the new toasts use the same advanced settings for how long to appear.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If I were reading the code and I saw this on its own:

await testSubject.click('saveSearchSuccess toastCloseButton');

It would not be clear to me why we're closing a toast that we haven't even looked at yet. The code implies the toast exists, but it doesn't verify this. I might even remove this code thinking that cleanup doesn't matter in this case, completely overlooking the role it plays as an assertion.

For me, the intent behind the code is clearer with two explicit actions: 1) the verification of success and 2) the removal of the toast to clean up the UI.

Only concern is that they do disappear after awhile

They'll disappear after a few seconds, but as soon as existsOrFail finds the toast, doesn't it resolve the promise? So there won't be any delay between these two actions, right?

Copy link
Contributor

Choose a reason for hiding this comment

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

They'll disappear after a few seconds, but as soon as existsOrFail finds the toast, doesn't it resolve the promise?

yes

So there won't be any delay between these two actions, right?

Well, there is still a delay, just a very minor one, like, whatever time it takes the code to execute the next line.

The code implies the toast exists, but it doesn't verify this.

We don't add manual assertions that any given button exists, for instance, before we click it. Actually, we kind of do, but it's part of the click function, so we don't have to add a manual check before every click call. What this is doing is adding that manual call that already exists inside the click function.

I might even remove this code thinking that cleanup doesn't matter in this case, completely overlooking the role it plays as an assertion.

sgtm. We seem to be doing well with flakiness so maybe this doesn't do anything extra.

I guess the way I see it is the only thing this code does is add a very slight potential for extra flakiness by having a check for "existsOrFail" and then the subsequent click. What if, for instance, the "existsOrFail" function ends up searching through a bunch of DOM elements before it gets to the toast, so that function call takes a few seconds to return true, then before the next line can execute, the toast disappears. Unlikely (especially because the existsOfFail check takes max 1 s), but maybe possible?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We don't add manual assertions that any given button exists, for instance, before we click it. Actually, we kind of do, but it's part of the click function, so we don't have to add a manual check before every click call.

I think I understand how you're approaching this. I think you're looking at this from the angle of "How do we remove points of failure", which I totally get. I'm looking at it from the point of view of "How do we make this code clear to the reader", which is an orthogonal concern to yours.

What if, for instance, the "existsOrFail" function ends up searching through a bunch of DOM elements before it gets to the toast, so that function call takes a few seconds to return true, then before the next line can execute, the toast disappears.

I think what you're saying makes sense. I think this is possible and it's a valid concern. Though I'm not sure what's the best way to satisfy both of our concerns.

Copy link
Contributor

Choose a reason for hiding this comment

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

The code implies the toast exists, but it doesn't verify this. I might even remove this code thinking that cleanup doesn't matter in this case, completely overlooking the role it plays as an assertion.

Sorry, I read this wrong earlier. I thought you were saying you were actually going to remove the code you added because it doesn't matter.

I'm confused by your intentions with this PR. Initially I thought your goal was to avoid flakiness.
Then after re-reading your comment above, I thought your goal was to extend the tests. Now I'm re-reading the primary git issue comment, and it's indeed to fix a flaky test?

If you want to extend the tests to make them more robust (fail more often than they otherwise might now), I can see why you would add both lines (primarily want to make sure the toast is there, secondarily I want to dismiss it).

Or are you trying to reduce flakiness by first making sure the toast exists before dismissing it? In which case, the first line is pointless.

I'm just confused by what actually fixes the flakiness of the other test. You wrote

Fixes #20810 by asserting that the search has saved by checking for the presence of a success toast.

But that doesn't make sense to me, why would adding a more thorough check cause it to pass? If it does pass, it seems like it's accidental (like the extra check is similar to adding a little sleep and hence, you don't hit whatever you were hitting before).

I suppose it doesn't too much matter. You can check this code in and maybe it'll accidentally help with stability, but it seems like there is an underlying issue that might show up later.

@elasticmachine
Copy link
Contributor

💔 Build Failed

@elasticmachine
Copy link
Contributor

💔 Build Failed

@@ -329,12 +329,6 @@ export function CommonPageProvider({ getService, getPageObjects }) {
});
}

async closeToast() {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think we should strive for very specific, intentional actions. A "toast" on its own is meaningless... what matters it what the toast represents, e.g. success, failure, etc. As we make changes to our UX we could replace this toast with a callout or a checkmark icon somewhere in the UI. A test which clicks a button and then looks for a toast representative of a successful outcome will be easier to understand and update than a test which just closes an open toast.

@elasticmachine
Copy link
Contributor

💔 Build Failed

@cjcenizal
Copy link
Contributor Author

23:50:23    │ proc  [ftr]        └-> exits when the text button is clicked on
23:50:23    │ proc  [ftr]          └-> "before each" hook: global before each
23:50:23    │ proc  [ftr]          │ debg  TestSubjects.find(exitFullScreenModeLogo)
23:50:23    │ proc  [ftr]          │ debg  findByCssSelector [data-test-subj~="exitFullScreenModeLogo"]
23:50:23    │ proc  [ftr]          │ debg  TestSubjects.click(exitFullScreenModeText)
23:50:23    │ proc  [ftr]          │ debg  TestSubjects.find(exitFullScreenModeText)
23:50:23    │ proc  [ftr]          │ debg  findByCssSelector [data-test-subj~="exitFullScreenModeText"]
23:50:23    │ proc  [ftr]          │ debg  TestSubjects.exists(globalNav)
23:50:23    │ proc  [ftr]          │ debg  existsByDisplayedByCssSelector [data-test-subj~="globalNav"]
23:50:24    │ proc  [ftr]          │ debg  TestSubjects.exists(top-nav)
23:50:24    │ proc  [ftr]          │ debg  existsByDisplayedByCssSelector [data-test-subj~="top-nav"]
23:50:25    │ proc  [ftr]          │ debg  --- tryForTime error: expected false to equal true
23:51:01    │ proc  [ftr]          │ debg  TestSubjects.exists(globalNav)
23:51:01    │ proc  [ftr]          │ debg  existsByDisplayedByCssSelector [data-test-subj~="globalNav"]
23:51:02    │ proc  [ftr]          │ debg  TestSubjects.exists(top-nav)
23:51:02    │ proc  [ftr]          │ debg  existsByDisplayedByCssSelector [data-test-subj~="top-nav"]
23:51:03    │ proc  [ftr]          │ debg  --- tryForTime errored again with the same message  ...
23:51:04    │ proc  [ftr]          │ info  Taking screenshot "/var/lib/jenkins/workspace/elastic+kibana+pull-request+multijob-selenium/kibana/test/functional/screenshots/failure/dashboard app using current data full screen mode exits when the text button is clicked on.png"
23:51:04    │ proc  [ftr]          │ info  Current URL is: http://localhost:5620/app/kibana#/dashboard/a66e4dd0-912e-11e8-abe7-631d10f4f8f9?_g=()&_a=(description:%27%27,filters:!(),fullScreenMode:!t,options:(darkTheme:!f,hidePanelTitles:!f,useMargins:!t),panels:!((embeddableConfig:(),gridData:(h:15,i:%271%27,w:24,x:0,y:0),id:%27145ced90-3dcb-11e8-8660-4d65aa086b3c%27,panelIndex:%271%27,type:visualization,version:%276.3.0%27),(embeddableConfig:(),gridData:(h:15,i:%272%27,w:24,x:24,y:0),id:e2023110-3dcb-11e8-8660-4d65aa086b3c,panelIndex:%272%27,type:visualization,version:%276.3.0%27),(embeddableConfig:(),gridData:(h:15,i:%273%27,w:24,x:0,y:15),id:%274b5d6ef0-3dcb-11e8-8660-4d65aa086b3c%27,panelIndex:%273%27,type:visualization,version:%276.3.0%27)),query:(language:lucene,query:%27%27),timeRestore:!f,title:%27full%20screen%20test%27,viewMode:view)
23:51:04    │ proc  [ftr]          │ info  Saving page source to: /var/lib/jenkins/workspace/elastic+kibana+pull-request+multijob-selenium/kibana/test/functional/failure_debug/html/dashboard app using current data full screen mode exits when the text button is clicked on.html
23:51:04    │ proc  [ftr]        └- ✖ fail: "dashboard app using current data full screen mode exits when the text button is clicked on"
23:51:04    │ proc  [ftr]        │        tryForTime timeout: Error: expected false to equal true
23:51:04    │ proc  [ftr]        │           at Assertion.assert (/var/lib/jenkins/workspace/elastic+kibana+pull-request+multijob-selenium/kibana/node_modules/expect.js/index.js:96:13)
23:51:04    │ proc  [ftr]        │           at Assertion.be.Assertion.equal (/var/lib/jenkins/workspace/elastic+kibana+pull-request+multijob-selenium/kibana/node_modules/expect.js/index.js:216:10)
23:51:04    │ proc  [ftr]        │           at Assertion.(anonymous function) [as be] (/var/lib/jenkins/workspace/elastic+kibana+pull-request+multijob-selenium/kibana/node_modules/expect.js/index.js:69:24)
23:51:04    │ proc  [ftr]        │           at retry.try (/var/lib/jenkins/workspace/elastic+kibana+pull-request+multijob-selenium/kibana/test/functional/apps/dashboard/_full_screen_mode.js:76:36)
23:51:04    │ proc  [ftr]        │           at <anonymous>
23:51:04    │ proc  [ftr]        │           at process._tickCallback (internal/process/next_tick.js:188:7)
23:51:04    │ proc  [ftr]        │         Error: tryForTime timeout: Error: expected false to equal true
23:51:04    │ proc  [ftr]        │         at Assertion.assert (node_modules/expect.js/index.js:96:13)
23:51:04    │ proc  [ftr]        │         at Assertion.be.Assertion.equal (node_modules/expect.js/index.js:216:10)
23:51:04    │ proc  [ftr]        │         at Assertion.(anonymous function) [as be] (node_modules/expect.js/index.js:69:24)
23:51:04    │ proc  [ftr]        │         at retry.try (test/functional/apps/dashboard/_full_screen_mode.js:76:36)
23:51:04    │ proc  [ftr]        │         at <anonymous>
23:51:04    │ proc  [ftr]        │         at process._tickCallback (internal/process/next_tick.js:188:7)
23:51:04    │ proc  [ftr]        │         at attempt (test/common/services/retry.js:38:17)
23:51:04    │ proc  [ftr]        │         at tryCatcher (node_modules/bluebird/js/main/util.js:26:23)
23:51:04    │ proc  [ftr]        │         at Promise._settlePromiseFromHandler (node_modules/bluebird/js/main/promise.js:503:31)
23:51:04    │ proc  [ftr]        │         at Promise._settlePromiseAt (node_modules/bluebird/js/main/promise.js:577:18)
23:51:04    │ proc  [ftr]        │         at Promise._settlePromises (node_modules/bluebird/js/main/promise.js:693:14)
23:51:04    │ proc  [ftr]        │         at Async._drainQueue (node_modules/bluebird/js/main/async.js:123:16)
23:51:04    │ proc  [ftr]        │         at Async._drainQueues (node_modules/bluebird/js/main/async.js:133:10)
23:51:04    │ proc  [ftr]        │         at Immediate.Async.drainQueues (node_modules/bluebird/js/main/async.js:15:14)
23:51:04    │ proc  [ftr]        │       
23:51:04    │ proc  [ftr]        │       
23:51:04    │ proc  [ftr]        └-> "after all" hook
23:51:04    │ proc  [ftr]      └-> "after all" hook
23:51:04    │ proc  [ftr]        │ debg  click Visualize tab
23:51:04    │ proc  [ftr]        │ debg  clickSelector(a[href*='visualize'])
23:51:04    │ proc  [ftr]        │ debg  clickByCssSelector(a[href*='visualize'])
23:51:04    │ proc  [ftr]        │ debg  findByCssSelector a[href*='visualize']
23:51:04    │ proc  [ftr]        │ debg  --- tryForTime error: [POST http://localhost:9515/session/19846fdbf31cb0e99bab84de46720938/element/0.11348278263745026-21/click] element not visible
23:51:04    │ proc  [ftr]        │         (Session info: chrome=65.0.3325.162)
23:51:04    │ proc  [ftr]        │         (Driver info: chromedriver=2.36.540471 (9c759b81a907e70363c6312294d30b6ccccc2752),platform=Linux 4.4.0-1050-aws x86_64)
23:51:05    │ proc  [ftr]        │ debg  findByCssSelector a[href*='visualize']
23:51:05    │ proc  [ftr]        │ debg  --- tryForTime errored again with the same message  ...
23:51:06    │ proc  [ftr]        │ debg  findByCssSelector a[href*='visualize']
23:51:06    │ proc  [ftr]        │ debg  --- tryForTime errored again with the same message  ...
23:51:06    │ proc  [ftr]        │ debg  findByCssSelector a[href*='visualize']
23:51:06    │ proc  [ftr]        │ debg  --- tryForTime errored again with the same message  ...
23:51:07    │ proc  [ftr]        │ debg  findByCssSelector a[href*='visualize']
23:51:07    │ proc  [ftr]        │ debg  --- tryForTime errored again with the same message  ...
23:51:07    │ proc  [ftr]        │ debg  findByCssSelector a[href*='visualize']
23:51:07    │ proc  [ftr]        │ debg  --- tryForTime errored again with the same message  ...
23:51:45    │ proc  [ftr]        │ info  Taking screenshot "/var/lib/jenkins/workspace/elastic+kibana+pull-request+multijob-selenium/kibana/test/functional/screenshots/failure/dashboard app using current data _after all_ hook.png"
23:51:45    │ proc  [ftr]        │ info  Current URL is: http://localhost:5620/app/kibana#/dashboard/a66e4dd0-912e-11e8-abe7-631d10f4f8f9?_g=()&_a=(description:%27%27,filters:!(),fullScreenMode:!t,options:(darkTheme:!f,hidePanelTitles:!f,useMargins:!t),panels:!((embeddableConfig:(),gridData:(h:15,i:%271%27,w:24,x:0,y:0),id:%27145ced90-3dcb-11e8-8660-4d65aa086b3c%27,panelIndex:%271%27,type:visualization,version:%276.3.0%27),(embeddableConfig:(),gridData:(h:15,i:%272%27,w:24,x:24,y:0),id:e2023110-3dcb-11e8-8660-4d65aa086b3c,panelIndex:%272%27,type:visualization,version:%276.3.0%27),(embeddableConfig:(),gridData:(h:15,i:%273%27,w:24,x:0,y:15),id:%274b5d6ef0-3dcb-11e8-8660-4d65aa086b3c%27,panelIndex:%273%27,type:visualization,version:%276.3.0%27)),query:(language:lucene,query:%27%27),timeRestore:!f,title:%27full%20screen%20test%27,viewMode:view)
23:51:45    │ proc  [ftr]        │ info  Saving page source to: /var/lib/jenkins/workspace/elastic+kibana+pull-request+multijob-selenium/kibana/test/functional/failure_debug/html/dashboard app using current data _after all_ hook.html
23:51:45    │ proc  [ftr]      └- ✖ fail: "dashboard app using current data "after all" hook"
23:51:45    │ proc  [ftr]      │        tryForTime timeout: [POST http://localhost:9515/session/19846fdbf31cb0e99bab84de46720938/element/0.11348278263745026-21/click] element not visible

image

@cjcenizal
Copy link
Contributor Author

Retest

@@ -56,8 +55,6 @@ export function DashboardVisualizationProvider({ getService, getPageObjects }) {
}

await PageObjects.discover.saveSearch(name);
await PageObjects.header.waitUntilLoadingHasFinished();
await testSubjects.exists('saveSearchSuccess');
Copy link
Contributor

Choose a reason for hiding this comment

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

how come no replacement with the dismissing of toast here?

Copy link
Contributor

Choose a reason for hiding this comment

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

oh nm you probably moved it into saveSearch, haven't gotten there yet.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right, PageObjects.discover.saveSearch() now checks for and closes the toast.

Copy link
Contributor

@stacey-gammon stacey-gammon left a comment

Choose a reason for hiding this comment

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

lgtm pending multiple passing ci's, looks like maybe more flakiness or hitting other new flakiness? But code changes lgtm.

@cjcenizal
Copy link
Contributor Author

cjcenizal commented Jul 27, 2018

@stacey-gammon Sorry, I wasn't clear about how I think this PR addresses the original issue. I think this removes the flakiness reported in the original issue by waiting for the success toast to verify the search has been saved before proceeding to the assertion on the query name. My theory is that the waitUntilLoadingHasFinished is flawed because it checks if the loading indicator is visible and, if it isn't, continues on as if the wait was successful. But what if the check happens before the indicator has time to appear? In that case the test can race on ahead of the UI. Waiting for the toast to appear seems like a more reliable way of ensuring the search is saved and we can continue with the test.

I think this PR then snowballed a bit when I checked for this pattern elsewhere and found the closeToast helper. At that point it seemed like a good idea to apply this pattern consistently. This is where I think the changes are more about improving readability than flakiness, though if any of these changes happened to occur in situations where waitUntilLoadingHasFinished is also in use, then we would make headway against flakiness there as well (assuming my hypothesis is correct).

Does this make sense?

@elasticmachine
Copy link
Contributor

💔 Build Failed

@cjcenizal
Copy link
Contributor Author

cjcenizal commented Jul 27, 2018

Looks like a legit failure related to my changes. The goal of this week is to create flaky tests, right?!

01:27:49    │ proc  [ftr]            │ debg  findByCssSelector [data-test-subj~="confirmSaveDashboardButton"]
01:27:49    │ info  [o.e.c.m.MetaDataIndexTemplateService] [xEg3bya] adding template [kibana_index_template:.kibana] for index patterns [.kibana]
01:27:49    │ proc  [ftr]            │ debg  isGlobalLoadingIndicatorVisible
01:27:49    │ proc  [ftr]            │ debg  TestSubjects.exists(globalLoadingIndicator)
01:27:49    │ proc  [ftr]            │ debg  existsByDisplayedByCssSelector [data-test-subj~="globalLoadingIndicator"]
01:27:49    │ proc  [ftr]            │ debg  awaitGlobalLoadingIndicatorHidden
01:27:49    │ proc  [ftr]            │ debg  TestSubjects.find(globalLoadingIndicator-hidden)
01:27:49    │ proc  [ftr]            │ debg  findByCssSelector [data-test-subj~="globalLoadingIndicator-hidden"]
01:27:49    │ proc  [ftr]            │ debg  TestSubjects.existOrFail(saveDashboardSuccess)
01:27:49    │ proc  [ftr]            │ debg  TestSubjects.exists(saveDashboardSuccess)
01:27:49    │ proc  [ftr]            │ debg  existsByDisplayedByCssSelector [data-test-subj~="saveDashboardSuccess"]
01:27:49    │ proc  [ftr]            │ debg  TestSubjects.click(saveDashboardSuccess toastCloseButton)
01:27:49    │ proc  [ftr]            │ debg  TestSubjects.find(saveDashboardSuccess toastCloseButton)
01:27:49    │ proc  [ftr]            │ debg  findByCssSelector [data-test-subj~="saveDashboardSuccess"] [data-test-subj~="toastCloseButton"]
01:27:49    │ proc  [ftr]            │ info  Taking screenshot "/var/lib/jenkins/workspace/elastic+kibana+pull-request+multijob-selenium/kibana/test/functional/screenshots/failure/dashboard app using legacy data dashboard time dashboard without stored timed is saved.png"
01:27:49    │ proc  [ftr]            │ info  Current URL is: http://localhost:5620/app/kibana#/dashboard/455d7c60-913c-11e8-bd8b-a3f2f9d5adf3?_g=()&_a=(description:%27%27,filters:!(),fullScreenMode:!f,options:(darkTheme:!f,hidePanelTitles:!f,useMargins:!t),panels:!((embeddableConfig:(),gridData:(h:15,i:%271%27,w:24,x:0,y:0),id:Visualization-PieChart,panelIndex:%271%27,type:visualization,version:%277.0.0-alpha1%27)),query:(language:lucene,query:%27%27),timeRestore:!f,title:%27Dashboard%20Test%20Time%27,viewMode:view)
01:27:49    │ proc  [ftr]            │ info  Saving page source to: /var/lib/jenkins/workspace/elastic+kibana+pull-request+multijob-selenium/kibana/test/functional/failure_debug/html/dashboard app using legacy data dashboard time dashboard without stored timed is saved.html
01:27:49    │ proc  [ftr]          └- ✖ fail: "dashboard app using legacy data dashboard time dashboard without stored timed is saved"
01:27:49    │ proc  [ftr]          │        Error: expected undefined to sort of equal true

image

…cessary waitUntilLoadingHasFinished calls where toasts are now used to verify success.
@elasticmachine
Copy link
Contributor

💔 Build Failed

@cjcenizal
Copy link
Contributor Author

Getting there...

02:48:52    │ proc  [ftr]          │ debg  Flipping save as new checkbox
02:48:53    │ proc  [ftr]          │ debg  clicking final Save button for named dashboard
02:48:53    │ proc  [ftr]          │ debg  TestSubjects.click(confirmSaveDashboardButton)
02:48:53    │ proc  [ftr]          │ debg  TestSubjects.find(confirmSaveDashboardButton)
02:48:53    │ proc  [ftr]          │ debg  findByCssSelector [data-test-subj~="confirmSaveDashboardButton"]
02:48:53    │ info  [o.e.c.m.MetaDataIndexTemplateService] [2XYLn7a] adding template [kibana_index_template:.kibana] for index patterns [.kibana]
02:48:53    │ proc  [ftr]          │ debg  TestSubjects.existOrFail(saveDashboardSuccess)
02:48:53    │ proc  [ftr]          │ debg  TestSubjects.exists(saveDashboardSuccess)
02:48:53    │ proc  [ftr]          │ debg  existsByDisplayedByCssSelector [data-test-subj~="saveDashboardSuccess"]
02:48:54    │ proc  [ftr]          │ info  Taking screenshot "/var/lib/jenkins/workspace/elastic+kibana+pull-request+multijob-selenium/kibana/test/functional/screenshots/failure/dashboard app using current data full screen mode available in view mode.png"
02:48:54    │ proc  [ftr]          │ info  Current URL is: http://localhost:5620/app/kibana#/dashboard/991a66f0-9147-11e8-a768-c9dd41f64643?_g=()&_a=(description:%27%27,filters:!(),fullScreenMode:!f,options:(darkTheme:!f,hidePanelTitles:!f,useMargins:!t),panels:!((embeddableConfig:(),gridData:(h:15,i:%271%27,w:24,x:0,y:0),id:%27145ced90-3dcb-11e8-8660-4d65aa086b3c%27,panelIndex:%271%27,type:visualization,version:%276.3.0%27),(embeddableConfig:(),gridData:(h:15,i:%272%27,w:24,x:24,y:0),id:e2023110-3dcb-11e8-8660-4d65aa086b3c,panelIndex:%272%27,type:visualization,version:%276.3.0%27),(embeddableConfig:(),gridData:(h:15,i:%273%27,w:24,x:0,y:15),id:%274b5d6ef0-3dcb-11e8-8660-4d65aa086b3c%27,panelIndex:%273%27,type:visualization,version:%276.3.0%27)),query:(language:lucene,query:%27%27),timeRestore:!f,title:%27full%20screen%20test%27,viewMode:view)
02:48:54    │ proc  [ftr]          │ info  Saving page source to: /var/lib/jenkins/workspace/elastic+kibana+pull-request+multijob-selenium/kibana/test/functional/failure_debug/html/dashboard app using current data full screen mode available in view mode.html
02:48:55    │ proc  [ftr]        └- ✖ fail: "dashboard app using current data full screen mode available in view mode"
02:48:55    │ proc  [ftr]        │        Error: expected false to equal true

image

@cjcenizal
Copy link
Contributor Author

These last two fixes have been interesting.

The first one required me to remove the explicit assertions in the tests in favor of the implicit ones in the saveDashboard method. I'm not happy about this, but I couldn't think of a better way to do it. I also removed the calls to waitUntilLoadingHasFinished which were made redundant by the toast checks.

The second one was a doozy. I watched the test execute locally and what happens is the toast shows up, the close button becomes visible (indicating the mouse is hovering over the toast), but then nothing happens -- the toast is never closed. When run in verbose mode, the output shows the click request is sent through and gets back an OK response. Looking through the toast code, it's possible that the click is being ignored by the component. I need to dig into this before merging this PR -- if it's something in the toast then maybe we can solve this in EUI instead of in our functional tests. For the time being, waiting a few ms before clicking the toast solved the problem so at least we can see if we can get a successful CI run.

Copy link
Contributor

@bmcconaghy bmcconaghy left a comment

Choose a reason for hiding this comment

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

Left some comments. Not sure that we should merge this if we suspect it has caused other test failures unless we fix those failures or can demonstrate they are unrelated. Also FYI my github account is bmcconaghy. billm is probably wondering why he got tagged on this ;-)

const isDashboardSaved = await PageObjects.dashboard.saveDashboard(dashboardName, { storeTimeWithDashboard: false });
expect(isDashboardSaved).to.eql(true);
// saveDashboard asserts that it saves successfully.
await PageObjects.dashboard.saveDashboard(dashboardName, { storeTimeWithDashboard: false });
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe rename the saveDashboard method to make it clear that it ensures the save, since the same comment is used in more than one place to indicate that?

const isCopiedToClipboard = await PageObjects.discover.clickCopyToClipboard();
expect(isCopiedToClipboard).to.eql(true);
// This method is self-confirming, so we don't need an assertion.
await PageObjects.discover.clickCopyToClipboard();
Copy link
Contributor

Choose a reason for hiding this comment

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

same as above, maybe indicate the self-confirming nature of this method in its name.

…. Ensure exit full screen button exists before clicking it.
@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@cjcenizal
Copy link
Contributor Author

Thanks for the review billm @bmcconaghy! I addressed your comments.

@stacey-gammon
Copy link
Contributor

I'm with @bmcconaghy - I don't think we should merge this unless we are sure it didn't cause the other flakiness. Now that @spalger added the build to track failures, we can better see if a test is flaky in master or here. Alternatively we could create a PR to run the other suspected flaky tests 20x and see if it hits any failures.

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@cjcenizal
Copy link
Contributor Author

Retest

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@elasticmachine
Copy link
Contributor

💔 Build Failed

@cjcenizal
Copy link
Contributor Author

I'm giving up on trying to account for animation within the functional tests themselves. I think that @spalger's direction in #21629 holds more promise. I just pushed a commit which removes all animations (modals, flyouts, toasts) to see if this reduces flakiness. If it does, then I'll block this PR on his.

@elasticmachine
Copy link
Contributor

💔 Build Failed

@elasticmachine
Copy link
Contributor

💔 Build Failed

@cjcenizal
Copy link
Contributor Author

This one again:

00:59:44    │ proc  [ftr]        └-> exits when the full screen logo button is clicked on
00:59:44    │ proc  [ftr]          └-> "before each" hook: global before each
00:59:44    │ proc  [ftr]          │ debg  TestSubjects.exists(exitFullScreenModeButton)
00:59:44    │ proc  [ftr]          │ debg  existsByDisplayedByCssSelector [data-test-subj~="exitFullScreenModeButton"]
00:59:44    │ proc  [ftr]          │ debg  TestSubjects.click(exitFullScreenModeButton)
00:59:44    │ proc  [ftr]          │ debg  TestSubjects.find(exitFullScreenModeButton)
00:59:44    │ proc  [ftr]          │ debg  findByCssSelector [data-test-subj~="exitFullScreenModeButton"]
00:59:45    │ proc  [ftr]          │ debg  TestSubjects.exists(globalNav)
00:59:45    │ proc  [ftr]          │ debg  existsByDisplayedByCssSelector [data-test-subj~="globalNav"]
00:59:46    │ proc  [ftr]          │ debg  TestSubjects.exists(top-nav)
00:59:46    │ proc  [ftr]          │ debg  existsByDisplayedByCssSelector [data-test-subj~="top-nav"]
00:59:47    │ proc  [ftr]          │ debg  --- tryForTime error: expected false to equal true
00:59:47    │ proc  [ftr]          │ debg  TestSubjects.exists(globalNav)
00:59:47    │ proc  [ftr]          │ debg  existsByDisplayedByCssSelector [data-test-subj~="globalNav"]
00:59:48    │ proc  [ftr]          │ debg  TestSubjects.exists(top-nav)
00:59:48    │ proc  [ftr]          │ debg  existsByDisplayedByCssSelector [data-test-subj~="top-nav"]
button is clicked on.html
01:00:25    │ proc  [ftr]        └- ✖ fail: "dashboard app using current data full screen mode exits when the full screen logo button is clicked on"
01:00:25    │ proc  [ftr]        │        tryForTime timeout: Error: expected false to equal true

image

@cjcenizal
Copy link
Contributor Author

#21704 will fix this ^

@elasticmachine
Copy link
Contributor

💔 Build Failed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants