-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Preview: Open preview to previewLink if not autosaveable #7703
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code here makes sense but it looks like a few tests are failing. For me, locally, three PostPreviewButton
tests are failing:
Summary of all failing tests
FAIL editor/components/post-preview-button/test/index.js
● PostPreviewButton › setPreviewWindowLink() › should do nothing if the preview window is already at url location
expect(jest.fn()).not.toHaveBeenCalled()
Expected mock function not to be called but it was called with:
["https://wordpress.org"]
38 | wrapper.instance().setPreviewWindowLink( url );
39 |
> 40 | expect( setter ).not.toHaveBeenCalled();
41 | } );
42 |
43 | it( 'set preview window location to url', () => {
at Object.<anonymous> (editor/components/post-preview-button/test/index.js:40:25)
● PostPreviewButton › saveForPreview() › should save if not dirty for new post
expect(jest.fn()).toHaveBeenCalled()
Expected mock function to have been called.
112 |
113 | if ( isExpectingSave ) {
> 114 | expect( autosave ).toHaveBeenCalled();
115 | expect( preventDefault ).toHaveBeenCalled();
116 | expect( window.open ).toHaveBeenCalled();
117 | expect( wrapper.instance().previewWindow.document.write ).toHaveBeenCalled();
at assertForSave (editor/components/post-preview-button/test/index.js:114:24)
at Object.<anonymous> (editor/components/post-preview-button/test/index.js:137:4)
● PostPreviewButton › saveForPreview() › should open a popup window
expect(jest.fn()).toHaveBeenCalled()
Expected mock function to have been called.
112 |
113 | if ( isExpectingSave ) {
> 114 | expect( autosave ).toHaveBeenCalled();
115 | expect( preventDefault ).toHaveBeenCalled();
116 | expect( window.open ).toHaveBeenCalled();
117 | expect( wrapper.instance().previewWindow.document.write ).toHaveBeenCalled();
at assertForSave (editor/components/post-preview-button/test/index.js:114:24)
at Object.<anonymous> (editor/components/post-preview-button/test/index.js:146:4)
Test Suites: 1 failed, 2 skipped, 196 passed, 197 of 199 total
Tests: 3 failed, 7 skipped, 1773 passed, 1783 total
Snapshots: 64 passed, 64 total
Time: 36.748s
Ran all test suites.
and one e2e test:
FAIL test/e2e/specs/preview.test.js
Preview
✕ Should open a preview window for a new post (2612ms)
● Preview › Should open a preview window for a new post
Error: failed to find element matching selector ".entry-title"
at Frame.$eval (node_modules/puppeteer/lib/FrameManager.js:344:13)
|
||
/** | ||
* Clicks the preview button and returns the generated preview window page, | ||
* either the newly created tab or the redirected existing target. This is |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haha, this is definitely one of those "I am frustrated" comment blocks 😄
test/e2e/specs/preview.test.js
Outdated
) ) ); | ||
} | ||
|
||
const [ , previewPage ] = await Promise.all( [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huh, I've never seen that before! TIL
// Open a popup, BUT: Set it to a blank page until save completes. This | ||
// is necessary because popups can only be opened in response to user | ||
// interaction (click), but we must still wait for the post to save. | ||
event.preventDefault(); | ||
this.previewWindow = window.open( | ||
'about:blank', | ||
previewLink ? previewLink : 'about:blank', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, previewLink || 'about:blank'
might be a bit nicer than the ternary, but it's just a style thing really.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case,
previewLink || 'about:blank'
might be a bit nicer than the ternary, but it's just a style thing really.
I'd agree, though to the general point this sort of clever use of ||
and &&
can sometimes bite when people think only of the fallback case, but not the fall...-forward (?) case, i.e. not anticipating the evaluation to the falsey value as actually being the assignment.
// false || null
null
// 0 && null
0
The latter one is a common pain-point in React where people have the tendency to do things like:
array.length && (
<ul>{ /* ... */ }</ul>
)
...not anticipating that when the array is empty, there will be the 0
as output.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Heh, true I guess. I wouldn't ever think to use array.length && ( […] )
but if others do: fair enough!
@@ -38,11 +38,9 @@ export class PostPreviewButton extends Component { | |||
*/ | |||
setPreviewWindowLink( url ) { | |||
const { previewWindow } = this; | |||
if ( ! previewWindow || previewWindow.location.href === url ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: I found that previewWindow.location.href
was not returning the value I expected: For the new window, it would return the URL of the editor tab, not the window. (Chrome 67.0.3396.99)
625a79a
to
f757da6
Compare
Previously we would allow the previous link to be reused; now we force to about:blank to write the empty interstitial message
@tofumatt The general "autosave exists at the beginning of post" is still problematic after this, yes, mentioned also in the original comment:
Seems like it may be the same for you. There's more to be done here with accounting for the initial autosave, which is why I was more inclined to save it for #7416. |
Okay, sounds good. The tests are passing for me now, just running a bit more locally but looking good. Should be another few minutes. |
Loading a published post with no autosaves hangs for me:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My opinion is… if you think this is better (I like the tests) then I’m fine with it.
It's still pretty buggy, but I don't think it's worse. 🤷♂️
If you think we should punt to 3.3, that's fine. If you think merging is better, do so.
Debugging a bit, I think the behavior in Firefox may be slightly different than anticipated, where |
Unload can be triggered in Firefox merely by the writing to the interstitial window. Only delete once a redirect has been evaluated (and not closed).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested new version in Firefox and it's much better. No more errors in the console and previews for new posts with no autosaves work.
Gotta fix some unit tests first for the new changes, will merge after updates pass Travis. |
previewWindow is deleted from the instance once props are set, but reference object location is mutated directly
Closes #7561
This pull request seeks to address set of issues related to the hanging preview interstitial "Please wait..." screen. The specific issue is caused by the fact that an
autosave
is attempted and then aborted by the corresponding effect because it is not autosaveable. Particularly, this can occur with the artificial dirtying of a published post autosave; the post is technically dirty, but cannot be autosaved since the fields are identical to the last autosave.It also incidentally resolves an issue where the preview window can occasionally prompt the user about unsaved changes when being closed. This was a very subtle bug in the following line of code:
gutenberg/editor/components/post-preview-button/index.js
Line 101 in 299f406
...a combination of:
delete
operator returning true on a successful deletiononbeforeunload
handler returningtrue
having the impact of a prompt being shownThere is one remaining buggy case here:
When reloading a post which has an autosave, if the user immediately presses Preview, the preview window will hang. This is due to the fact that our state is unaware of the presence of an existing autosave, and therefore assumes that autosave is valid, even if no changes are made.
gutenberg/editor/store/selectors.js
Lines 379 to 382 in 299f406
I am classifying this as falling under the scope of #7416.
Testing instructions:
Verify that pressing "Preview" loads the accurate preview of the post, with no hanging "Please wait..." screen. Try a variety of conditions:
Ensure end-to-end tests pass: