test(functional): open every page as a guest, a member and the staff
RouteCrawlTest reads the routes from the router and opens every GET route that
needs no placeholder filled, three times over: 145 routes, 434 visits. A new page
is covered the moment it is declared. Every page has to answer without a server
error, finish the document it starts and put the CSRF token into each form that
posts; the panel has to let nobody in but the staff, and the staff has to be
refused nothing. The one page left out for the staff reads the version of MySQL,
which SQLite does not have.
When a page answers 500, the test asks again with catch: false, a new argument
of handleRequest(), and reports the exception the kernel would have logged, so
the cause shows in CI as well.
FunctionalUserFactory hashes the shared password once per process. bcrypt costs
a tenth of a second here, and the crawl alone signs in about three hundred
accounts: 46 seconds against 6.