Skip to content

Commit 49013b8

Browse files
authored
[MV3 Debug Extension] Fix authentication issue for the Dart Debug Extension (#2026)
1 parent c8d4439 commit 49013b8

File tree

3 files changed

+109
-11
lines changed

3 files changed

+109
-11
lines changed

dwds/debug_extension_mv3/web/debug_session.dart

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ Future<bool> _authenticateUser(int tabId) async {
563563
type: StorageObject.debugInfo,
564564
tabId: tabId,
565565
);
566-
final authUrl = debugInfo?.authUrl;
566+
final authUrl = debugInfo?.authUrl ?? _authUrl(debugInfo?.extensionUrl);
567567
if (authUrl == null) {
568568
await _showWarningNotification('Cannot authenticate user.');
569569
return false;
@@ -742,6 +742,19 @@ class _DebugSession {
742742
}
743743
}
744744

745+
String? _authUrl(String? extensionUrl) {
746+
if (extensionUrl == null) return null;
747+
final authUrl = Uri.parse(extensionUrl).replace(path: authenticationPath);
748+
switch (authUrl.scheme) {
749+
case 'ws':
750+
return authUrl.replace(scheme: 'http').toString();
751+
case 'wss':
752+
return authUrl.replace(scheme: 'https').toString();
753+
default:
754+
return authUrl.toString();
755+
}
756+
}
757+
745758
@JS()
746759
@anonymous
747760
class _EvalResponse {

dwds/test/puppeteer/extension_test.dart

Lines changed: 94 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,13 @@ import 'dart:io';
1515

1616
import 'package:collection/collection.dart';
1717
import 'package:dwds/data/debug_info.dart';
18+
import 'package:dwds/data/extension_request.dart';
19+
import 'package:dwds/src/servers/extension_backend.dart';
20+
import 'package:dwds/src/utilities/server.dart';
1821
import 'package:path/path.dart' as p;
19-
import 'package:puppeteer/puppeteer.dart';
22+
import 'package:puppeteer/puppeteer.dart' hide Response;
23+
import 'package:shelf/shelf.dart';
24+
import 'package:shelf_static/shelf_static.dart';
2025
import 'package:test/test.dart';
2126
import 'package:test_common/test_sdk_configuration.dart';
2227

@@ -777,25 +782,32 @@ void main() async {
777782
}
778783
});
779784

780-
group('connected to a fake app', () {
781-
final fakeAppPath = webCompatiblePath(
785+
group('Backwards-compatible with older DWDS versions', () {
786+
final port = 8080;
787+
final hostname = 'localhost';
788+
final fakeAppUrl = 'http://$hostname:$port/index.html';
789+
final fakeAppDir = webCompatiblePath(
782790
p.split(
783791
absolutePath(
784792
pathFromDwds: p.join(
785793
'test',
786794
'puppeteer',
787795
'fake_app',
788-
'index.html',
789796
),
790797
),
791798
),
792799
);
793-
final fakeAppUrl = 'file://$fakeAppPath';
794800
late Browser browser;
801+
late HttpServer server;
795802
Worker? worker;
796803
Page? backgroundPage;
797804

798805
setUpAll(() async {
806+
server = await _fakeServer(
807+
hostname: hostname,
808+
port: port,
809+
assetPath: fakeAppDir,
810+
);
799811
browser = await puppeteer.launch(
800812
headless: false,
801813
timeout: Duration(seconds: 60),
@@ -824,15 +836,19 @@ void main() async {
824836
});
825837

826838
tearDownAll(() async {
839+
await server.close();
827840
await browser.close();
828841
});
829842

830-
// Note: This tests that the debug extension still works for DWDS versions
831-
// <17.0.0. Those versions don't send the debug info with the ready event.
832-
// Therefore the values are read from the Window object.
843+
// Note: This tests that the extension works for DWDS versions <17.0.0.
844+
// Those versions don't send the debug info with the ready event
845+
// (https://github.com/dart-lang/webdev/pull/1772). Therefore the values
846+
// are read from the Window object.
833847
test('reads debug info from Window and saves to storage', () async {
834848
// Navigate to the "Dart" app:
835-
await navigateToPage(browser, url: fakeAppUrl, isNew: true);
849+
final appTab =
850+
await navigateToPage(browser, url: fakeAppUrl, isNew: true);
851+
836852
// Verify that we have debug info for the fake "Dart" app:
837853
final appTabId = await _getTabId(
838854
fakeAppUrl,
@@ -853,6 +869,56 @@ void main() async {
853869
expect(debugInfo.isFlutterApp, isFalse);
854870
expect(debugInfo.appOrigin, isNotNull);
855871
expect(debugInfo.appUrl, isNotNull);
872+
873+
// Close the tab:
874+
await appTab.close();
875+
});
876+
877+
// Note: This tests that the extension works for DWDS versions <18.0.0.
878+
// Those versions don't support authentication from the injected client
879+
// (https://github.com/dart-lang/webdev/pull/1916). Therefore the auth
880+
// request is sent from the extension itself.
881+
test('clicking on extension icon authenticates the user', () async {
882+
// Navigate to the "Dart" app:
883+
final appTab =
884+
await navigateToPage(browser, url: fakeAppUrl, isNew: true);
885+
886+
// Wait for debug info to be saved:
887+
final appTabId = await _getTabId(
888+
fakeAppUrl,
889+
worker: worker,
890+
backgroundPage: backgroundPage,
891+
);
892+
final debugInfoKey = '$appTabId-debugInfo';
893+
final debugInfo = await _fetchStorageObj<DebugInfo>(
894+
debugInfoKey,
895+
storageArea: 'session',
896+
worker: worker,
897+
backgroundPage: backgroundPage,
898+
);
899+
900+
// Verify that the extension URL has been saved (this is what is used
901+
// by the extension to create the auth url):
902+
expect(debugInfo.extensionUrl, isNotNull);
903+
904+
// Click on the extension icon:
905+
await clickOnExtensionIcon(
906+
worker: worker,
907+
backgroundPage: backgroundPage,
908+
);
909+
910+
// Verify that the user is now authenticated:
911+
final authKey = '$appTabId-isAuthenticated';
912+
final isAuthenticated = await _fetchStorageObj<String>(
913+
authKey,
914+
storageArea: 'session',
915+
worker: worker,
916+
backgroundPage: backgroundPage,
917+
);
918+
expect(isAuthenticated, equals('true'));
919+
920+
// Close the tab:
921+
await appTab.close();
856922
});
857923
});
858924
});
@@ -1052,3 +1118,22 @@ Future<void> _takeScreenshot(
10521118
p.join('test', 'puppeteer', 'test_images', '$screenshotName.png');
10531119
await File(screenshotPath).writeAsBytes(screenshot);
10541120
}
1121+
1122+
Future<HttpServer> _fakeServer({
1123+
required String hostname,
1124+
required int port,
1125+
required String assetPath,
1126+
}) async {
1127+
final server = await startHttpServer(hostname, port: port);
1128+
final staticHandler = createStaticHandler(assetPath);
1129+
final cascade = Cascade().add(staticHandler).add(_fakeAuthHandler);
1130+
serveHttpRequests(server, cascade.handler, (e, s) {});
1131+
return server;
1132+
}
1133+
1134+
Response _fakeAuthHandler(request) {
1135+
if (request.url.path == authenticationPath) {
1136+
return Response.ok(authenticationResponse);
1137+
}
1138+
return Response.notFound('Not found');
1139+
}

dwds/test/puppeteer/fake_app/main.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ document.addEventListener("DOMContentLoaded", function(event) {
22
window['$dartEntrypointPath'] = 'DART_ENTRYPOINT_PATH';
33
window['$dartAppId'] = 'DART_APP_ID';
44
window['$dartAppInstanceId'] = 'DART_APP_INSTANCE_ID';
5-
window['$dartExtensionUri'] = 'DART_EXTENSION_URI';
5+
window['$dartExtensionUri'] = 'http://localhost:8080/extensionPath';
66
window['$isInternalBuild'] = true;
77
window['$isFlutterApp'] = false;
88
setTimeout(() => {

0 commit comments

Comments
 (0)