qunit - what our current tests are written in - has support for a Chrome Remote Debugging backend. Iām not sure if theyāll work out of the box due to the fixtures stuff, though. And Iām not sure if itās possible to write true integration tests with just the qunit API.
Ideally would be a Ruby interface to the remote debugging port, to coordinate tests of things like a thread live-updating over the message bus when a new post is made.
# Set up
browser.log_in(user1)
browser_2.log_in(user2)
topic = create_topic(user1, ...)
browser.navigate("/t/#{topic.id}")
browser_2.navigate("/t/#{topic.id}").wait!
browser.wait!
# Action: Create a post in the thread
## or make this into a helper function that manages the composer
browser_2.click('#topic-footer-buttons button.create')
browser_2.type_post('#reply-control .d-editor-textarea-wrapper textarea', "A reply to the topic that satisfies minimum length requirements")
th = Thread.new do ||
browser.wait_for_message_bus
end
browser_2.click('#reply-control .submit-panel button')
browser_2.wait!
# Check: Post is created on the server
topic.reload
expect(topic.posts.count).to eq(2)
# Check: post is delivered to other browser
new_post = topic.posts.last
th.join # browser.wait_for_message_bus
expect(browser.find_element("article[data-post-id=\"#{new_post.id}\"]")).to #not be nil, I forget how to spell that
Iāve had a play with getting the qunit tests running in headless chrome, and it seems to work alright. The performance improvement isnāt as dramatic as Iād hoped - on my computer phantomjs runs the core tests in 227s, and headless chrome runs them in 201s.
Iāve written a JS script, which depends on a couple of NPM modules: chrome-launcher and chrome-remote-interface, which provide an interface to the Chrome Remote Debugging system @riking mentioned.
Iāve then given the rake qunit:test an optional third parameter to use chrome instead of phantomJS. Set the USE_CHROME environment variable to use chrome instead of phantomJS
So, assuming you have chrome and node/npm installed, using it works like this:
Having a look at this at the moment. It looks to me like PhantomJS is currently included in the base image.
Is there any reason for this, and if not shall I move it to only be in the dev/test images? Seems to me like unnecessary bulk for the image used in every install of Discourse. On the other hand, itās only 22mb, so not a big deal ĀÆ\_(ć)_/ĀÆ
Yeah it was kind of āhistoricalā cause you can not run the smoke test without it. But I am open to just moving this stuff out, we will just have to be careful with our CI.
I think for the time being just add chrome to the dev/test image and we will move to that.
Thereās some magic that occurs to obtain phantomJS
The build.rb script executes the download_phantomjs script on the host, which spins up a docker container, which Iām guessing builds a custom version of phantomJS.
So if you run that download_phantomjs script first it should work
Something I just stumbled across is Puppeteer, which is created and maintained by the Chromium devtools team. It bundles a version of chromium that skips all the UI dependencies, bringing it in at just under 100mb. Seems like a far tidier option than having to install chrome separately and use a third party library for the API.
It requires node 7 though, so not an option for Discourse quite yet (discourse_docker ships the LTS version, which is version 6). Maybe once version 8 LTS is released in October it could be an option.
The API looks very similar to the chrome-remote-interface module Iāve used, so hopefully will be trivial to switch over once the time comes
Oh cool, in that case Iāll have a quick look at it next week. What are the critical things that depend on node/npm in Discourse? (so I can check they donāt break)
Am I correct in saying most of the critical stuff is run in mini-racer instead?
I also had a play with puppeteer, and it is much easier/cleaner than what I had before. Iāve published an NPM module to do exactly what we need - I figure it might be useful for other projects using QUnit. So once node has been upgraded it should be as simple as