Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion dwds/debug_extension_mv3/web/debug_session.dart
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,7 @@ Future<bool> _authenticateUser(int tabId) async {
type: StorageObject.debugInfo,
tabId: tabId,
);
final authUrl = debugInfo?.authUrl;
final authUrl = debugInfo?.authUrl ?? _authUrl(debugInfo?.extensionUrl);
if (authUrl == null) {
await _showWarningNotification('Cannot authenticate user.');
return false;
Expand Down Expand Up @@ -742,6 +742,19 @@ class _DebugSession {
}
}

String? _authUrl(String? extensionUrl) {
if (extensionUrl == null) return null;
final authUrl = Uri.parse(extensionUrl).replace(path: authenticationPath);
switch (authUrl.scheme) {
case 'ws':
return authUrl.replace(scheme: 'http').toString();
case 'wss':
return authUrl.replace(scheme: 'https').toString();
default:
return authUrl.toString();
}
}

@JS()
@anonymous
class _EvalResponse {
Expand Down
103 changes: 94 additions & 9 deletions dwds/test/puppeteer/extension_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,13 @@ import 'dart:io';

import 'package:collection/collection.dart';
import 'package:dwds/data/debug_info.dart';
import 'package:dwds/data/extension_request.dart';
import 'package:dwds/src/servers/extension_backend.dart';
import 'package:dwds/src/utilities/server.dart';
import 'package:path/path.dart' as p;
import 'package:puppeteer/puppeteer.dart';
import 'package:puppeteer/puppeteer.dart' hide Response;
import 'package:shelf/shelf.dart';
import 'package:shelf_static/shelf_static.dart';
import 'package:test/test.dart';
import 'package:test_common/test_sdk_configuration.dart';

Expand Down Expand Up @@ -777,25 +782,32 @@ void main() async {
}
});

group('connected to a fake app', () {
final fakeAppPath = webCompatiblePath(
group('Backwards-compatible with older DWDS versions', () {
final port = 8080;
final hostname = 'localhost';
final fakeAppUrl = 'http://$hostname:$port/index.html';
final fakeAppDir = webCompatiblePath(
p.split(
absolutePath(
pathFromDwds: p.join(
'test',
'puppeteer',
'fake_app',
'index.html',
),
),
),
);
final fakeAppUrl = 'file://$fakeAppPath';
late Browser browser;
late HttpServer server;
Worker? worker;
Page? backgroundPage;

setUpAll(() async {
server = await _fakeServer(
hostname: hostname,
port: port,
assetPath: fakeAppDir,
);
browser = await puppeteer.launch(
headless: false,
timeout: Duration(seconds: 60),
Expand Down Expand Up @@ -824,15 +836,19 @@ void main() async {
});

tearDownAll(() async {
await server.close();
await browser.close();
});

// Note: This tests that the debug extension still works for DWDS versions
// <17.0.0. Those versions don't send the debug info with the ready event.
// Therefore the values are read from the Window object.
// Note: This tests that the extension works for DWDS versions <17.0.0.
// Those versions don't send the debug info with the ready event
// (https://github.com/dart-lang/webdev/pull/1772). Therefore the values
// are read from the Window object.
test('reads debug info from Window and saves to storage', () async {
// Navigate to the "Dart" app:
await navigateToPage(browser, url: fakeAppUrl, isNew: true);
final appTab =
await navigateToPage(browser, url: fakeAppUrl, isNew: true);

// Verify that we have debug info for the fake "Dart" app:
final appTabId = await _getTabId(
fakeAppUrl,
Expand All @@ -853,6 +869,56 @@ void main() async {
expect(debugInfo.isFlutterApp, isFalse);
expect(debugInfo.appOrigin, isNotNull);
expect(debugInfo.appUrl, isNotNull);

// Close the tab:
await appTab.close();
});

// Note: This tests that the extension works for DWDS versions <18.0.0.
// Those versions don't support authentication from the injected client
// (https://github.com/dart-lang/webdev/pull/1916). Therefore the auth
// request is sent from the extension itself.
test('clicking on extension icon authenticates the user', () async {
// Navigate to the "Dart" app:
final appTab =
await navigateToPage(browser, url: fakeAppUrl, isNew: true);

// Wait for debug info to be saved:
final appTabId = await _getTabId(
fakeAppUrl,
worker: worker,
backgroundPage: backgroundPage,
);
final debugInfoKey = '$appTabId-debugInfo';
final debugInfo = await _fetchStorageObj<DebugInfo>(
debugInfoKey,
storageArea: 'session',
worker: worker,
backgroundPage: backgroundPage,
);

// Verify that the extension URL has been saved (this is what is used
// by the extension to create the auth url):
expect(debugInfo.extensionUrl, isNotNull);

// Click on the extension icon:
await clickOnExtensionIcon(
worker: worker,
backgroundPage: backgroundPage,
);

// Verify that the user is now authenticated:
final authKey = '$appTabId-isAuthenticated';
final isAuthenticated = await _fetchStorageObj<String>(
authKey,
storageArea: 'session',
worker: worker,
backgroundPage: backgroundPage,
);
expect(isAuthenticated, equals('true'));

// Close the tab:
await appTab.close();
});
});
});
Expand Down Expand Up @@ -1052,3 +1118,22 @@ Future<void> _takeScreenshot(
p.join('test', 'puppeteer', 'test_images', '$screenshotName.png');
await File(screenshotPath).writeAsBytes(screenshot);
}

Future<HttpServer> _fakeServer({
required String hostname,
required int port,
required String assetPath,
}) async {
final server = await startHttpServer(hostname, port: port);
final staticHandler = createStaticHandler(assetPath);
final cascade = Cascade().add(staticHandler).add(_fakeAuthHandler);
serveHttpRequests(server, cascade.handler, (e, s) {});
return server;
}

Response _fakeAuthHandler(request) {
if (request.url.path == authenticationPath) {
return Response.ok(authenticationResponse);
}
return Response.notFound('Not found');
}
2 changes: 1 addition & 1 deletion dwds/test/puppeteer/fake_app/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ document.addEventListener("DOMContentLoaded", function(event) {
window['$dartEntrypointPath'] = 'DART_ENTRYPOINT_PATH';
window['$dartAppId'] = 'DART_APP_ID';
window['$dartAppInstanceId'] = 'DART_APP_INSTANCE_ID';
window['$dartExtensionUri'] = 'DART_EXTENSION_URI';
window['$dartExtensionUri'] = 'http://localhost:8080/extensionPath';
window['$isInternalBuild'] = true;
window['$isFlutterApp'] = false;
setTimeout(() => {
Expand Down