-
Notifications
You must be signed in to change notification settings - Fork 20.6k
Simulate external servers with Node.js+Javascript instead of (Apache|mongoose|…)+PHP #1999
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
Comments
There is complication about that - testswarm requires ability to execute tests on any previous commit not just the current one. Otherwise it would done a long time ago. @Krinkle have more info about that. |
Or just move away from testswarm, as it was suggested by the infra team, browserstack-tunnel or karma our candidates for the replacement. But those requires some good amount of time to do it, at least karma does, which is my preference. |
Intern looks like an option as well jquery/testswarm@dd6002f |
Does intern offers qunit support? I was under impression it has its own framework. /cc @csnover |
You could certainly load QUnit into it if you wanted (I have heard of some people dumping Mocha in there), but it’s a kind of inception if you do since it comes with quite robust unit testing built-in :) I’ve actually got a mostly-working branch with a full* QUnit API compatible interface so, with only a small amount of work to address the TODOs (probably only a day or two of work?), you should be able to drop existing QUnit tests into Intern by wrapping them with (And then, fingers crossed!, I can convince team QUnit to come over & help me get cool new stuff into Intern more quickly :))) * Well it was, prior to the most recent QUnit release. Now it is slightly outdated, but it should be easy to update, since from what I could see the QUnit update was adding some features that Intern already has so it’s easy to map them |
Brain dump:
As long as TestSwarm is used (unless you're okay with ajax tests not running in TestSwarm), we can't have entry points not automatically served by common installations of Apache and nginx (hence PHP was used). Any server set up by Grunt won't exist by the time TestSwarm distributes the test urls to BrowserStack. These test urls point at the not-so-static "static" web server serving build artefacts from Jenkins jobs for upto 30 days at unique subdirectories (html/js/css and php, served by nginx). It can also be re-ran from TestSwarm at any point in the future (within 30 days). Even if we'd remove the re-run feature in TestSwarm, QUnit would still have to know about the hostname and port the server is on. And the url would have to be publicly exposed to BrowserStack. Though of course, this wouldn't be an issue if it was using an ssh tunnel to BrowserStack. But I'm not sure that is feasible in the current testswarm-browserstack setup. |
For the purposes of CI generally (as opposed to local development) and TestSwarm in particular, I imagine we'd still use the stable servers for builds.jenkins.jquery.com/jquery/{build}/… URLs, they'd just defer to grunt-managed node.js servers for dynamic responses. There are many ways to skin this cat, but here's one example:
// Connect to already-running server listening at port specified in the runfile
tryConnecting();
function tryConnecting() {
try {
port = fs.readFileSync( runfile );
req = http.get({ port: port || "invalid" }, function() {
console.log( "Server running at port " + port );
});
// On failure, try to _start_ a server
req.on( "error", tryStarting );
} catch ( err ) {
tryStarting( err );
}
}
function tryStarting( err ) {
console.warn( err.message );
// Lock the runfile for our use
lockfile.lock(
runfile,
{
// Consider existing locks stale after 7 seconds
stale: 7000,
// Try acquisition for up to 7 seconds (2x backoff per retry)
{ retries: 3, minTimeout: 1000 }
},
function( err, release ) {
// Got the lock
if ( !err ) {
var keepAlive = grunt.config( "connect.testServer.keepAlive" ),
onCreate = grunt.config( "connect.testServer.onCreateServer" );
// Server creation listener
onCreate.push(function( server, connect, options ) {
console.log( "Server running at port " + options.port );
// Write out the runfile and register a shutdown listener to clear it
fs.writeFileSync( runfile, options.port + "" );
server.on( "close", function() {
fs.writeFile( runfile, "" );
release();
});
// Schedule a deferable future shutdown
if ( keepAlive ) {
grunt.config( "connect.testServer.shutdown" ) =
setTimeout( server.close.bind( server ), keepAlive );
}
});
// Start the server daemon (only self-terminating by the above)
grunt.task.run( "connect:testServer:keepalive" );
// If we lost a race for the lock, try connecting to the winner
} else if ( err.code === "ELOCKED" ) {
console.warn( "Couldn't get lock on " + runfile );
tryConnecting();
// Bail on any other error
} else {
throw err;
}
}
);
} |
Since I was summoned already and so am seeing replies on this, I would just also point out that Dojo core has a JSGI server for mock services set up with its Intern test suite, so you don’t need to do much work again, you could just take that code and adapt it for your own use. It’s used to do the same thing the jQuery PHP test scripts are used for (testing Dojo’s I/O code). The services are in the |
Regarding incompatibility between TestSwarm (which independently and outside the Grunt/Jenkins run context) and Travis CI / local development, we can use the More likely though, from what I can tell there isn't any need for the urls to vary. We could easily implement the same urls both ways. The Ajax tests are already written with the expectation that they are served over HTTP (e.g. any static server will work, and if served over We'd configure out Node.js server to similarly serve all files statically, with a non-static router (that has higher precedence) for our Ajax server mocks. E.g. route Once that is fixed, we can run the unit tests normally with QUnit/Karma/Grunt, e.g. defaulting to Headless Chrome, and we can run them Travis CI in at least Headless Chrome and Firefox (pre-installed). In addition, once they pass in e.g. Headless Chrome, we can go run them in various other browsers using Saucelabs or BrowserStack as various other jQuery projects do already. All this can happen whilst the tests will continue to work in TestSwarm as well. (If desired) |
* Add 'grunt karma:main' task that runs tests via Karma. - Karma uses its own server and uses its own HTML page by default. All files to be served are registered, and for the most part also loaded ("included") through Karma. - Use the 'customContextFile' option, because: * Preserve the qunit-fixture we have. * Workaround karma-qunit bug. - Use the 'customDebugFile' option, because (above reasons) and: * Create 'qunit' element and load QUnit CSS styles for easier debugging. * Base URI - Karma opens at /context.html and serves test/ files from /base/test/. This is incompatible with our manual run which is at /test/index.html. - Using a <base href> tag with "/base/test/" fixed most tests when trying it out, but still caused three problems: 1. While <base href> fixes native expansion (e.g. in HTML attributes, in CSS, and when passed to XHR), it did affect in-JS expansion in our tests, which use hacks based on location.href (e.g. for <a> property tests in unit/basic.js, and creation of absolute urls by unit/ajax.js). Fix those by introducing a prependUrlBase() function that prepends document.baseURI instead of location.href 2. A test in unit/manipulation.js clicks on an anchor link. This broke the test entirely by navigating away from the test page since href="jquery#2" would now expand to /base/test/jquery#2. Fix those by: - Remove the <base> tag again. - Revert the logic in prependUrlBase() to how it used to be inlined. - Remove prependUrlBase() from basic/attributes test. - Instead, fix url() to have baseURL be "/base/test/" when in Karma. - Apply url() to bare urls: - unit/core.js (globalEval test) - unit/support.js (csp test) * In addition to all the above, the most time-consuming part still was making the Ajax tests pass because they currently assume being served from Apache with mod_php installed. I originally planned on addressing this by starting another Node server before Karma starts, somehow injecting its url, and stopping it after Karma. Instead, let's try to use Karma's support for middleware to (hopefully) make this prettier. Fixes jquery#1999.
* Add 'grunt karma:main' task that runs tests via Karma. - Karma uses its own server and uses its own HTML page by default. All files to be served are registered, and for the most part also loaded ("included") through Karma. - Use the 'customContextFile' option, because: * Preserve the qunit-fixture we have. * Workaround karma-qunit bug. - Use the 'customDebugFile' option, because (above reasons) and: * Create 'qunit' element and load QUnit CSS styles for easier debugging. * Base URI - Karma opens at /context.html and serves test/ files from /base/test/. This is incompatible with our manual run which is at /test/index.html. - Using a <base href> tag with "/base/test/" fixed most tests when trying it out, but still caused three problems: 1. While <base href> fixes native expansion (e.g. in HTML attributes, in CSS, and when passed to XHR), it did affect in-JS expansion in our tests, which use hacks based on location.href (e.g. for <a> property tests in unit/basic.js, and creation of absolute urls by unit/ajax.js). Fix those by introducing a prependUrlBase() function that prepends document.baseURI instead of location.href 2. A test in unit/manipulation.js clicks on an anchor link. This broke the test entirely by navigating away from the test page since href="jquery#2" would now expand to /base/test/jquery#2. Fix those by: - Remove the <base> tag again. - Revert the logic in prependUrlBase() to how it used to be inlined. - Remove prependUrlBase() from basic/attributes test. - Instead, fix url() to have baseURL be "/base/test/" when in Karma. - Apply url() to bare urls: - unit/core.js (globalEval test) - unit/support.js (csp test) * In addition to all the above, the most time-consuming part still was making the Ajax tests pass because they currently assume being served from Apache with mod_php installed. I originally planned on addressing this by starting another Node server before Karma starts, somehow injecting its url, and stopping it after Karma. Instead, let's try to use Karma's support for middleware to (hopefully) make this prettier. Fixes jquery#1999.
* Add 'grunt karma:main' task that runs tests via Karma. - Karma uses its own server and uses its own HTML page by default. All files to be served are registered, and for the most part also loaded ("included") through Karma. - Use the 'customContextFile' option, because: * Preserve the qunit-fixture we have. * Workaround karma-qunit bug. - Use the 'customDebugFile' option, because (above reasons) and: * Create 'qunit' element and load QUnit CSS styles for easier debugging. * Base URI - Karma opens at /context.html and serves test/ files from /base/test/. This is incompatible with our manual run which is at /test/index.html. - Using a <base href> tag with "/base/test/" fixed most tests when trying it out, but still caused three problems: 1. While <base href> fixes native expansion (e.g. in HTML attributes, in CSS, and when passed to XHR), it did affect in-JS expansion in our tests, which use hacks based on location.href (e.g. for <a> property tests in unit/basic.js, and creation of absolute urls by unit/ajax.js). Fix those by introducing a prependUrlBase() function that prepends document.baseURI instead of location.href 2. A test in unit/manipulation.js clicks on an anchor link. This broke the test entirely by navigating away from the test page since href="jquery#2" would now expand to /base/test/jquery#2. Fix those by: - Remove the <base> tag again. - Revert the logic in prependUrlBase() to how it used to be inlined. - Remove prependUrlBase() from basic/attributes test. - Instead, fix url() to have baseURL be "/base/test/" when in Karma. - Apply url() to bare urls: - unit/core.js (globalEval test) - unit/support.js (csp test) * In addition to all the above, the most time-consuming part still was making the Ajax tests pass because they currently assume being served from Apache with mod_php installed. I originally planned on addressing this by starting another Node server before Karma starts, somehow injecting its url, and stopping it after Karma. Instead, let's try to use Karma's support for middleware to (hopefully) make this prettier. Fixes jquery#1999.
* Add 'grunt karma:main' task that runs tests via Karma. - Karma uses its own server and uses its own HTML page by default. All files to be served are registered, and for the most part also loaded ("included") through Karma. - Use the 'customContextFile' option, because: * Preserve the qunit-fixture we have. * Workaround karma-qunit bug. - Use the 'customDebugFile' option, because (above reasons) and: * Create 'qunit' element and load QUnit CSS styles for easier debugging. * Base URI - Karma opens at /context.html and serves test/ files from /base/test/. This is incompatible with our manual run which is at /test/index.html. - Using a <base href> tag with "/base/test/" fixed most tests when trying it out, but still caused three problems: 1. While <base href> fixes native expansion (e.g. in HTML attributes, in CSS, and when passed to XHR), it did affect in-JS expansion in our tests, which use hacks based on location.href (e.g. for <a> property tests in unit/basic.js, and creation of absolute urls by unit/ajax.js). Fix those by introducing a prependUrlBase() function that prepends document.baseURI instead of location.href 2. A test in unit/manipulation.js clicks on an anchor link. This broke the test entirely by navigating away from the test page since href="jquery#2" would now expand to /base/test/jquery#2. Fix those by: - Remove the <base> tag again. - Revert the logic in prependUrlBase() to how it used to be inlined. - Remove prependUrlBase() from basic/attributes test. - Instead, fix url() to have baseURL be "/base/test/" when in Karma. - Apply url() to bare urls: - unit/core.js (globalEval test) - unit/support.js (csp test) * Move definition of 'isSwarm' and 'basicTests' out of loadTests(), given Karma will run without that function. * In addition to all the above, the most time-consuming part still was making the Ajax tests pass because they currently assume being served from Apache with mod_php installed. I originally planned on addressing this by starting another Node server before Karma starts, somehow injecting its url, and stopping it after Karma. Instead, let's try to use Karma's support for middleware to (hopefully) make this prettier. Fixes jquery#1999.
* Add 'grunt karma:main' task that runs tests via Karma. - Karma uses its own server and uses its own HTML page by default. All files to be served are registered, and for the most part also loaded ("included") through Karma. - Use the 'customContextFile' option, because: * Preserve the qunit-fixture we have. * Workaround karma-qunit bug. - Use the 'customDebugFile' option, because (above reasons) and: * Create 'qunit' element and load QUnit CSS styles for easier debugging. * Move definition of 'isSwarm' and 'basicTests' out of loadTests(), given Karma will run without that function. * In addition to all the above, the most time-consuming part still was making the Ajax tests pass because they currently assume being served from Apache with mod_php installed. I originally planned on addressing this by starting another Node server before Karma starts, somehow injecting its url, and stopping it after Karma. Instead, let's try to use Karma's support for middleware to (hopefully) make this prettier. Fixes jquery#1999.
* Add 'grunt karma:main' task that runs tests via Karma. - Karma uses its own server and uses its own HTML page by default. All files to be served are registered, and for the most part also loaded ("included") through Karma. - Use the 'customContextFile' option, because: * Preserve the qunit-fixture we have. * Workaround karma-qunit bug. - Use the 'customDebugFile' option, because (above reasons) and: * Create 'qunit' element and load QUnit CSS styles for easier debugging. * Move definition of 'isSwarm' and 'basicTests' out of loadTests(), given Karma will run without that function. * In addition to all the above, start porting some of the PHP mocks to Node.js. (The Ajax tests currently assume being served from Apache with mod_php.). I originally planned on addressing this by starting another Node server before Karma starts, somehow injecting its url, and stopping it after Karma. Instead, let's try to use Karma's support for middleware to (hopefully) make this prettier. Ref issue jquerygh-1999, pull jquerygh-3744.
* Merge all PHP stubs into one MockServer class. * Complete the middleware-mockserver.js port (Node.js equivalent). Notes: * Merge action=script, and action=evalScript. (Similar) * Merge action=wait, action=longLoadScript, action=dont_return. (Similar) * Merge action=status, and action=nocontent. (Similar) * Renamed text.php to text.txt. (No PHP code) * Change 404.php reference to 404.txt. (Neither exists) * Remove data/test.php. (Unused) Now that all tests pass, also add 'grunt karma:main' to npm test. Fixes jquery#1999.
* Merge all PHP stubs into one MockServer class. * Complete the middleware-mockserver.js port (Node.js equivalent). Notes: * Merge action=script, and action=evalScript. (Similar) * Merge action=wait, action=longLoadScript, action=dont_return. (Similar) * Merge action=status, and action=nocontent. (Similar) * Renamed text.php to text.txt. (No PHP code) * Change 404.php reference to 404.txt. (Neither exists) * Remove data/test.php. (Unused) Now that all tests pass, also add 'grunt karma:main' to npm test (for use in local development and on Travis CI). Also add a separate 'npm run jenkins' for use on jenkins.jquery.com where we won't run Chrome (runs TestSwarm instead). Fixes jquery#1999.
* Add 'grunt karma:main' task that runs tests via Karma. - Karma uses its own server and uses its own HTML page by default. All files to be served are registered, and for the most part also loaded ("included") through Karma. - Use the 'customContextFile' option, because: * Preserve the qunit-fixture we have. * Workaround karma-qunit bug. - Use the 'customDebugFile' option, because (above reasons) and: * Create 'qunit' element and load QUnit CSS styles for easier debugging. * Move definition of 'isSwarm' and 'basicTests' out of loadTests(), given Karma will run without that function. * In addition to all the above, start porting some of the PHP mocks to Node.js. (The Ajax tests currently assume being served from Apache with mod_php.). I originally planned on addressing this by starting another Node server before Karma starts, somehow injecting its url, and stopping it after Karma. Instead, let's try to use Karma's support for middleware to (hopefully) make this prettier. Ref issue jquerygh-1999, pull jquerygh-3744.
* Merge all PHP stubs into one MockServer class. * Complete the middleware-mockserver.js port (Node.js equivalent). Notes: * Merge action=script, and action=evalScript. (Similar) * Merge action=wait, action=longLoadScript, action=dont_return. (Similar) * Merge action=status, and action=nocontent. (Similar) * Renamed text.php to text.txt. (No PHP code) * Change 404.php reference to 404.txt. (Neither exists) * Remove data/test.php. (Unused) Now that all tests pass, also add 'grunt karma:main' to npm test (for use in local development and on Travis CI). Also add a separate 'npm run jenkins' for use on jenkins.jquery.com where we won't run Chrome (runs TestSwarm instead). Fixes jquery#1999.
* Merge all PHP stubs into one MockServer class. * Complete the middleware-mockserver.js port (Node.js equivalent). Notes: * Merge action=script, and action=evalScript. (Similar) * Merge action=wait, action=longLoadScript, action=dont_return. (Similar) * Merge action=status, and action=nocontent. (Similar) * Renamed text.php to text.txt. (No PHP code) * Merge references to 404.php, 404.html, and someFileThatDoesNotExist.html to 404.txt, and add a handler for the latter to test middleware to avoid warnings in the Karma server output. * Remove data/test.php. (Unused) Now that all tests pass, also add 'grunt karma:main' to npm test (for use in local development and on Travis CI). Also add a separate 'npm run jenkins' for use on jenkins.jquery.com where we won't run Chrome (runs TestSwarm instead). Fixes jquery#1999.
This will allow us to set up and tear down the server with grunt and track all dependencies in package.json, but requires reimplementing our PHP scripts and probably (hopefully?) also establishing a mechanism for communicating the listening port to QUnit.
The text was updated successfully, but these errors were encountered: