Skip to content

Commit

Permalink
Minimal integration test for dartdoc search bar. (#8056)
Browse files Browse the repository at this point in the history
  • Loading branch information
isoos committed Sep 16, 2024
1 parent 1e3830b commit 80c0c70
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 23 deletions.
44 changes: 31 additions & 13 deletions pkg/pub_integration/lib/src/test_browser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -182,13 +182,23 @@ class TestBrowserSession {
await rq.continueRequest();
return;
}
// TODO: this file is missing, we may need to fix it in the dartdoc stylesheet
if (rq.url.endsWith('/css/search.svg')) {
await rq.respond(
status: 200,
body: '',
contentType: 'image/svg+xml',
headers: {'Cache-Control': 'public, max-age=604800'},
);
return;
}

final uri = Uri.parse(rq.url);
if (uri.path.contains('//')) {
serverErrors.add('Double-slash URL detected: "${rq.url}".');
}

await rq.continueRequest(headers: rq.headers);
await rq.continueRequest();
});

page.onResponse.listen((rs) async {
Expand All @@ -209,21 +219,29 @@ class TestBrowserSession {
try {
parseAndValidateHtml(await rs.text);
} catch (e) {
serverErrors.add('${rs.request.url} returned bad HTML: $e');
final url = rs.request.url;
if (url.contains('/documentation/') &&
url.endsWith('-sidebar.html')) {
// ignore dartdoc sidebars
} else {
serverErrors.add('$url returned bad HTML: $e');
}
}
}

final uri = Uri.parse(rs.url);
if (uri.pathSegments.length > 1 && uri.pathSegments.first == 'static') {
if (!uri.pathSegments[1].startsWith('hash-')) {
serverErrors.add('Static ${rs.url} is without hash URL.');
}

final cacheHeader = rs.headers[HttpHeaders.cacheControlHeader];
if (cacheHeader == null ||
!cacheHeader.contains('public') ||
!cacheHeader.contains('max-age')) {
serverErrors.add('Static ${rs.url} is without public caching.');
if (!rs.url.startsWith('data:')) {
final uri = Uri.parse(rs.url);
if (uri.pathSegments.length > 1 && uri.pathSegments.first == 'static') {
if (!uri.pathSegments[1].startsWith('hash-')) {
serverErrors.add('Static ${rs.url} is without hash URL.');
}

final cacheHeader = rs.headers[HttpHeaders.cacheControlHeader];
if (cacheHeader == null ||
!cacheHeader.contains('public') ||
!cacheHeader.contains('max-age')) {
serverErrors.add('Static ${rs.url} is without public caching.');
}
}
}
});
Expand Down
65 changes: 65 additions & 0 deletions pkg/pub_integration/test/dartdoc_search_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:convert';

import 'package:http/http.dart' as http;
import 'package:pub_integration/src/fake_test_context_provider.dart';
import 'package:pub_integration/src/test_browser.dart';
import 'package:puppeteer/puppeteer.dart';
import 'package:test/test.dart';

void main() {
group('dartdoc search', () {
late final TestContextProvider fakeTestScenario;
final httpClient = http.Client();

setUpAll(() async {
fakeTestScenario = await TestContextProvider.start();
});

tearDownAll(() async {
await fakeTestScenario.close();
httpClient.close();
});

test('bulk tests', () async {
final origin = fakeTestScenario.pubHostedUrl;
// Importing one package + local analysis
await httpClient.post(Uri.parse('$origin/fake-test-profile'),
body: json.encode({
'testProfile': {
'defaultUser': 'admin@pub.dev',
'packages': [
{'name': 'oxygen'},
],
},
'analysis': 'local',
}));

final user = await fakeTestScenario.createAnonymousTestUser();

// test keyboard navigation
await user.withBrowserPage((page) async {
await page.gotoOrigin('/documentation/oxygen/latest/');

await page.keyboard.press(Key.slash);
await Future.delayed(Duration(milliseconds: 200));
await page.keyboard.type('enum');
await Future.delayed(Duration(milliseconds: 200));
await page.keyboard.press(Key.arrowDown);
await Future.delayed(Duration(milliseconds: 200));
await page.keyboard.press(Key.enter);

await page.waitForNavigation();

// It is likely that we end up on the `TypeEnum.html` page, but we don't
// need to hardcode it here, in case dartdoc changes the order of the options.
expect(page.url,
startsWith('$origin/documentation/oxygen/latest/oxygen/'));
expect(page.url, endsWith('.html'));
});
});
}, timeout: Timeout.factor(testTimeoutFactor));
}
11 changes: 1 addition & 10 deletions pkg/pub_integration/test/search_completition_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,7 @@ void main() {

test('bulk tests', () async {
final origin = fakeTestScenario.pubHostedUrl;
// init server data
//
// The test profile import uses a fake analysis by default, which
// assigns tags with a pseudorandom process (based on the hash of the
// package's name and sometimes the version), with a few hardcoded
// patterns, e.g. `flutter_*` packages will get `sdk:flutter` tag assigned.
//
// This imports 100 packages with these semi-random tags, and adding and
// removing filters works because of the number of packages and their
// tags are kind of random.
// Importing one package + local analysis
await httpClient.post(Uri.parse('$origin/fake-test-profile'),
body: json.encode({
'testProfile': {
Expand Down

0 comments on commit 80c0c70

Please sign in to comment.