-
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
e2e test with selenium + browserstack for legacy browsers like IE. #21528
Conversation
Have you considered feasibility of this, from the perspective of pricing? Do you assume we can apply for free open-source testing ? Mentioned also in #16509 (comment) . If we need to apply and it's a reasonable-enough process, we should probably get this sorted . I see most value in having this as part of the Travis build. It's good if people can run it locally, but I don't think we can reliably assume people are going to that. Edit: I've started the process to apply for an open source testing account. |
I submitted an application for an open source testing account through BrowserStack, and was approved rather quickly. In considering how we'd want to implement this into our continuous integration, I'm especially conscious of how best to be careful with the credential keys. We can encrypt variables which, as noted in the documentation, would not be available to pull requests from forked repositories. If we're expecting these test runs to be quite slow, and they're not urgent in the sense of needing to block individual pull requests, we might be content to allow these to run only on commits to |
70cbb01
to
c00d48f
Compare
As WordPress is huge, I was quite sure that BrowserStack will grant a free open source account. (I guess most bosses and markerters want WordPress logo on their "trusted by" list.) But I couldn't believe that they also gave me one when I applied with my cloned Gutenberg repo. I totally agree with running these tests on master branch only. Actually, I was wondering how we should add other edge cases with other browsers like #20507 (safari), #21031(firefox + macOS). But by adding them on master branch only, we can group them with a name like "Travis CI - Browser issues" and add a job for each environment. (It's not considered in this PR.) p.s. I cannot understand why lint fails with a mysterious message, 'Cannot read property 'toUpperCase' of undefined'. It passes on the local Windows 10. |
@@ -0,0 +1,13 @@ | |||
# E2E Selenium | |||
|
|||
End-To-End (E2E) tests for WordPress written for legacy browsers. |
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.
I guess legacy
is a bit wrong here, this package might test edge cases in safari, firefox, or edge. Right?
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.
I guess
legacy
is a bit wrong here, this package might test edge cases in safari, firefox, or edge. Right?
Related to #21528 (comment) , I think it might depend on the scope of the issues we want to cover here. If we don't think we'll need it to be used for Firefox and Safari, then I think it's quite reasonable to document this as targeted toward legacy browsers. In fact, I think it could be preferable to further clarify the limited scope this package is intended to serve.
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.
I would be perfectly happy to have these tests running on IE only. None of the other browsers have caused (or are likely to cause) anywhere near as much trouble as IE.
What would be the impact of this on the Puppeteer-based e2e tests and tooling in the short and long term? |
@chrisvanpatten It's a new toolset. It doesn't affect any Puppeteer-based e2e tests. It's created for some edge cases that cannot be tested with Puppeteer like IE11, safari, etc. |
I like the line of thinking here. I'm especially conscious of the potential developer experience impact in bringing a second set of end-to-end testing tools, in addition the current Puppeteer workflow. I think we'd want to be very explicit in outlining the scope of this package as intending to cover the limited set of cases that we can't cover through those tools. But I'd also want to highlight Playwright, which is being developed by many of the original developers of Puppeteer, and which aims to increase coverage to additional browsers (including Firefox and Safari). It'd been discussed in one of the previous JavaScript meetings, and it might be something to keep an eye on and consider as a replacement for Puppeteer at some point in the future. So to try to "future-proof" the introduction of this module in light of potential future changes, I consider:
I'm also trying to consider its relationship amongst |
Puzzling indeed. I can try to check and see if I can reproduce it locally. Based on how the error is presented, it seems like it's an issue with one of the linting tools itself, not necessarily a problem in your code (i.e. not a reported lint issue, but an error occurring in the process of performing the lint). |
packages/e2e-selenium/tsconfig.json
Outdated
// commented out because src folder doesn't exist in this package. | ||
//"rootDir": "src", |
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.
There was some prior discussion at #18942 (comment) about folder structures for packages which aren't transpiled, using lib
as a substitute for src
. I believe this package in its current state is not prone to the same problems which were aimed to be addressed in having a lib
folder (files in the root of the project), but it would be good to have the consistency all the same.
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.
Fixed.
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.
But this breaks compressed size action. Should we roll back?
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.
I decided to use rootDirs
.
I've added this as a topic to be discussed during tomorrow's JavaScript meeting. I think it'll be good to get some extra attention on this 👍 |
1. I didn't know that playwright support safari. But it does. Then, it seems that focusing on IE is the better choice. When I was writing it, I thought there was no library that supports e2e test for safari except selenium. My idea was to e2e test everything with Chrome and other browser issues with selenium. But playwright can cover 3 major evergreen browsers. Then, following that way is better than my original thought. Then, changing the name to 2. AFAIK, selenium is the only option to e2e test IE. And locally setting up selenium IE driver is really tedious. (check here) And I guess we cannot manipulate the Internet options in CIs. As That's why I didn't include this in And these tests won't be written in Puppeteer or Playwright. In addition, they cannot be run together. So, they are not in And utils for these tests should be written for Selenium. They need different set of dependencies and structures. Therefore, they're not written in But I admit that I read those packages and borrowed ideas to create 3. When I was implementing this package, an idea that was bugging me was "Do we really need this?" IE is a legacy browser. It's slow and doesn't support ES2015+ and it won't. It's slowly losing market share. But that also made me think "when should we safely say that IE11 is dead" or "when is the safe time to say that it is better to use our time for other things than to maintain this ie test package?" As we all know, Microsoft won't release the next version of Windows 10 in the near future. (Their goal is to make it evergreen.) And IE is part of Windows 10. In other words, IE'll be always with us until Windows 10 is gone. It's really unlikely that Microsoft will announce the official death of IE. I've checked 2 browser market share sites and the market share of IE is 5.87% and 3.77%. It lost about 1.7-3% of market share in 2019. As browserslist default is >0.5%, we can safely drop IE in 2022~2024 assuming that IE loses its market share linearly. But the problem is that firefox is losing share at the same time. I hope when IE becomes under .5%, Firefox becomes something like 1.12%. |
c00d48f
to
eea3352
Compare
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.
This is working well! Just a few comments below. Then once it's merged, we'll be faced with the task of figuring out everything we should test for 😄
const stopBrowserStackLocal = async () => { | ||
return new Promise( ( resolve ) => { | ||
browserstackLocal.stop( function() { | ||
resolve(); |
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.
Shouldn't we add a reject
here in case there's an error?
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.
class Local {
start(options: Partial<Options>, callback: (error?: Error) => void): void;
isRunning(): boolean;
stop(callback: () => void): void;
}
As you can see, error is not returned as an argument. That's why there is no reject.
I added this as a comment.
@@ -0,0 +1,12 @@ | |||
module.exports = { | |||
setupFilesAfterEnv: [ | |||
//'@wordpress/jest-console', |
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.
Can this be removed?
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 Gutenberg, console.log
is not allowed by jest-console
. But I needed console.log
to print out the link to the result.
That's why it's commented out. When I solve the problem, it'll be uncommented.
const { login } = require( './login' ); | ||
const { createNewPost } = require( './create-new-post' ); | ||
|
||
const closeWelcomeGuide = async () => { |
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.
This function name is confusing because three different things happen here, and "close welcome guide" is probably the least significant of them. It would be clearer to name it something like loginAndCreateNewPost
or even navigateToEditor
.
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.
AFAIK, selenium doesn't have an evaluate
in Puppeteer. Because of that, we cannot write code like below in create-new-post
in test-utils
.
const isWelcomeGuideActive = await page.evaluate( () =>
wp.data.select( 'core/edit-post' ).isFeatureActive( 'welcomeGuide' )
);
if ( showWelcomeGuide !== isWelcomeGuideActive ) {
await page.evaluate( () =>
wp.data.dispatch( 'core/edit-post' ).toggleFeature( 'welcomeGuide' )
);
await page.reload();
}
All we can do is open up a new page in the beginning and close it programmatically by sending ESC key.
That's what it does: closing welcome guide for the first time.
Note. I tried to mimic the code above with driver.executeJavaScript
but failed. Because it tries to find an element right after reloading started.
That's why createNewPost
and closeWelcomeGuide
are separate functions.
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.
Perhaps I wasn't clear enough. My issue is with the function being called closeWelcomeGuide
, when what it is doing is:
- Login;
- create new post;
- close welcome guide.
It would be better to give this function a name that reflects all three of the things it does, instead of just the last one.
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.
How about fixing that in this way?
- Remove
login()
andcreateNewPost()
. - Call them in
beforeAll()
instead.
It's clearer than simply calling closeWelcomeGuide()
inside the beforeAll()
.
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.
Sure, that would work!
@@ -0,0 +1,7 @@ | |||
const createNewPost = async () => { | |||
await driver.get( 'http://localhost:8888/wp-admin/post-new.php' ); |
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.
It might be better to use localhost:8889
instead, as it's specifically set up for testing. 8888
being the environment used for development, tests might be affected by currently active plugins or other local changes.
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.
Fixed.
@@ -0,0 +1,13 @@ | |||
# E2E Selenium | |||
|
|||
End-To-End (E2E) tests for WordPress written for legacy browsers. |
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.
I would be perfectly happy to have these tests running on IE only. None of the other browsers have caused (or are likely to cause) anywhere near as much trouble as IE.
This has been discussed recently, in several places. It's a pretty popular topic 😅 |
I've felt a lot of uncertainty around "Which browsers do we test?", "How is this distinct from existing testing?", "Should we invest in this if Internet Explorer is on its way out?" One of the advantages of using a service like BrowserStack is that it supports many different combinations of operating system and browser. With that in mind, I think modeling this tooling as targeted toward testing regressions of specific issues under specific configuration of browser not otherwise covered by end-to-end tests may be a nice way to address all of the above questions:
As far as impact that has on the proposal:
|
global.d.ts doesn't work.
eea3352
to
5a7cbe6
Compare
1. After reading your comment, I realized that I forgot there are still differences between browsers. I agree with that this package is necessary even after IE is dead. 2. I think that the better name for this package should go without It seems that unclear name made us discuss "what is the difference between
3. It would be ideal if we can customize it('tests something', { preset: 'iphone-safari' }, async () => {
// test code.
}) it('test other thing', {
browserName: 'firefox',
os: 'Windows',
os_version: '8.1',
}, async () => {
// test code
}) And organize test files like below:
(I believe IE needs a special folder because most of them would be related with IE. And for others, let's start by adding them in a single list. When the list becomes big, we'll see the pattern and we'll naturally know how to organize them.) Maybe we can run the test like:
|
5b03a17
to
c7156c2
Compare
I could reproduce the lint failure on Ubuntu 18.04. Found out that the problem was on |
Reference to the meeting about this PR: click here. |
WordPress is dropping support for IE 11 later this year so this work is no longer necessary: https://make.wordpress.org/core/2021/03/25/discussion-summary-dropping-support-for-ie11/ Thank you for all the work done to explore this approach 🙇🏻 |
Description
How has this been tested?
npx wp-env start
.npm run dev
ornpm run build
.packages/e2e-selenium
folder..env.template
file and rename it to.env
. Fill the content of.env
. You can get the name and key by signing up browserstack. If you have any problem signing up or don't want to sign up for this, I'll share my username and key. Contact sainthkh at WordPress Slack.../../node_modules/.bin/jest --config=jest.config.js
.After a few minutes, you can see the message like below:
Then, you can watch the result by visiting the link. (Login is not required.)
Screenshots
Check above.
Types of changes
New testing feature.
Things to discuss.
1. How to show the result link.
Currently, I used
console.log()
to log it. But it's against the Gutenberg convention.process.stdout.write()
is overwritten by the jest result message. It cannot be used. I also usedprocess.stdout.on('data')
andprocess.on('exit')
, but they didn't work.My last option is to use
child_process.fork()
and IPC. But I hope there is simpler answer than this. If there's no other way than this, I need to use it.2. Moving the selenium+browserstack configuartion to packages/scripts?
I'm not sure this setup is useful for WordPress developers.
3. How to organize tests.
I created a folder,
ie
, undertest
folder. And create a test file with an issue number. It's because it takes really long to finish a test (10-20s a test or even longer). By breaking down a test file per issue, we can test them separately.Downside: It's hard to see what's going on from the name of the file. But I guess issue page contains more info than the file name. So, it don't think it's important.
4. Setting up BrowserStack and Travis CI.
To make this work with CI, we need an official BrowserStack account for Gutenberg team and set up environment variables.
I created
CI_BROWSERSTACK_USER
,CI_BROWSERSTACK_KEY
for them.Checklist: