Page MenuHomePhabricator

Implement SpecialPage for running javascript tests
Closed, ResolvedPublic

Description

As proposed on mw.org [1] we want to move away from the static unit testing for JavaScript and instead run it in the context of an actual MediaWiki environment that will open many doors, such as:

  • interacting with the real dom, not a static mini version in an .html file
  • ability for Extensions to register unit tests
  • running tests in different skins (usekin=.. )
  • Query the API

Krinkle

[1] http://www.mediawiki.org/wiki/Thread:Manual_talk:JavaScript_unit_testing/QUnit_/_TestSwarm_environment,_Version_2


Version: unspecified
Severity: enhancement

Details

Reference
bz30339
TitleReferenceAuthorSource BranchDest Branch
helm chart 1.1.0: Handle REGGIE_AUTH_REALMrepos/releng/reggie!67dancyreview/dancy/helm-chart-1.1.0main
Proper WWW-Authenticate responserepos/releng/reggie!66dancyreview/dancy/fix-jwtmain
Implement JWT authentication for writable endpointsrepos/releng/reggie!20demonjwt-authmain
Customize query in GitLab

Event Timeline

bzimport raised the priority of this task from to Medium.Nov 21 2014, 11:49 PM
bzimport set Reference to bz30339.

Roughly summarized the approach I plan to take:

  • Create a Special:UnitTesting page (disable user scripts, like preferences/login etc.)
  • By default shows a list, $par is the framework of choice
  • Special:UnitTesting/qunit
    • Outputs the QUnit html frame
    • Loads the jquery.qunit module and our testrunner
    • Loads the test suites from $wgUnitTestingQUnitSuites
  • $wgUnitTestingQUnitSuites is an array of module names (eg. array( 'jquery.byteLength.test' )).
  • The test suites are registered as resource modules in $wgResourceModules or Resources.php: 'jquery.byteLength.test' => array( 'scripts' => ...., 'dependencies' => 'jquery.byteLength' )

Created attachment 8919
First shot at implementing Special:UnitTesting infrastructure

attachment mw-unittesting-corepatch-2011-08-15.patch ignored as obsolete

Implementation details:

  • New Special:UnitTesting page (user scripts disabled, isListed returns false depending on $wgEnableSpecialUnitTesting)
  • Shows a list of frameworks, by default only qunit
  • [[Special:UnitTesting/qunit]] outputs the QUnit base html and loads testrunner (which loads jquery.qunit and the other stuff we need) + all test suites by passing $wgUnitTestingQUnitSuites to OutputPage's addModules().

TBD:

  • As can be seen in the patch in the comment above wgUnitTestingQUnitSuites in DefaultSettings, adding stuff for extensions looks a little funky. The reason is simple, we don't want all test suites to be registered unless wgEnableSpecialUnitTesting is true (to avoid polluting the start up module with a lot of crap and making it twice or three times as big). I also considered adding a global variable just for these modules and calling register() myself in the SpecialUnitTesting page, but that doesn't work either because load.php doesn't know on what page we are, so they wouldn't be registered. Plus, that would mess up or not work at all with caching since startup has (and should have) only 1 cache. StartUp should never depend on user or page. So I attempted to create a hook inside ResourceLoader->__construct() that is only ran if wgEnableSpecialUnitTesting is true. And if it is register the modules and add the array_keys of the modules to $wgUnitTestingQUnitSuites.

The problem is that didn't work because ResourceLoader->__construct() runs AFTER SpecialUnitTesting->execute(), so when SpecialUnitTesting->execute() did addModules( wgUnitTestingQUnitSuites ), nothing was added. That's why I work around this by letting extensions add their array keys to wgUnitTestingQUnitSuites in the global scope right away, and the registry separately through the hook. If anybody has a better solution, I would love to change it since I'm not liking this very much.

Problems:

  • When I applied this patch and set wgEnableSpecialUnitTesting to true, and visited [[Special:UnitTesting/qunit]], I got :

Uncaught RangeError: Maximum call stack size exceeded

in my console and none of the test suites was loaded. As a result many other modules are broken too. (such as Exception thrown by user.options: Cannot read property 'options' of undefined).

I suspect $.inArray in resolve() inside mw.loader's scope is doing something wrong.

cc'ing Roan. Can you figure out what's going on with $.inArray being recursed ?

(In reply to comment #4)

cc'ing Roan. Can you figure out what's going on with $.inArray being recursed ?

I don't have time for that right now, I'm sorry. It would help if you could obtain a backtrace (it seems Chrome/WebKit doesn't give you one, but Firebug should AFAIK), then use the debugger to try to find out why it's doing infinite recursion.

Forget the patch, I've got a better plan.

Created attachment 8976
Better patch

Changes since last patch:

  • Renamed infrastructure from "UnitTesting" to "JavaScriptTesting"
  • Moved the core test suites into a single module, instead of many separate ones
  • Using a hook to let extensions register modules (instead of keeping a global variable, and changing it on-run time, better not to move things into a global variable and pull them out again in another part of the code). General test module structure is a lot simpler and straight forward now.
  • Created loop to add 'qunit.testrunner' as a dependency to all qunit test modules. This is needed because no test should run until qunit and friends are loaded.

attachment bugzilla-attachment.diff ignored as obsolete

Oh crap, testrunner should only be added to dependencies of $testModules['qunit'] not to all of $testModules.

sumanah wrote:

Added the "patch" and "need-review" keywords; Mark hopes to get someone to review the patch soon.

I have created a branch named JSTesting from trunk@r100338 with r100339.
Your patch is in that branch since r100340.

I added some minor patches (see branch commits).

Is there any reason you are loading the QUnit module directly from the resource loader constructor? It would be better placed in includes/specials/SpecialJavaScriptTest.php constructor. Since those resources are only needed for the dedicated special pages, that sounds like a waste of cpu/memory for all the other requests.

Apart for this point above, seems it could be merged to core.

This patch is fairly outdated. The above concerns are also taken care of by me in a newer version.

I've committed it to the branch in r100392.