blob: ad23263d967a06635c5abbbf3a817f9aaf8d6d7f [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:mockito/mockito.dart';
import 'package:test/test.dart';
import 'package:webdriver/sync_core.dart';
import 'package:sl4f/sl4f.dart';
class MockPortForwarder extends Mock implements PortForwarder {}
class MockSl4f extends Mock implements Sl4f {}
class MockProcessHelper extends Mock implements ProcessHelper {}
class MockWebDriverHelper extends Mock implements WebDriverHelper {}
class MockWebDriver extends Mock implements WebDriver {}
const String testDutAddress = '192.168.1.1';
void main(List<String> args) {
MockSl4f sl4f;
MockPortForwarder portForwarder;
MockProcessHelper processHelper;
MockWebDriverHelper webDriverHelper;
WebDriverConnector webDriverConnector;
setUp(() {
sl4f = MockSl4f();
portForwarder = MockPortForwarder();
processHelper = MockProcessHelper();
webDriverHelper = MockWebDriverHelper();
webDriverConnector = WebDriverConnector('path/to/chromedriver', sl4f,
processHelper: processHelper,
webDriverHelper: webDriverHelper,
portForwarder: portForwarder);
});
test('webDriversForHost filters by host', () async {
final openContexts = {
20000: 'https://www.test.com/path/1',
20001: 'https://www.example.com/path/1',
20002: 'https://www.test.com/path/2',
20003: 'https://www.example.com/path/2'
};
mockAvailableWebDrivers(webDriverHelper, sl4f, portForwarder, openContexts);
final webDrivers =
await webDriverConnector.webDriversForHost('www.test.com');
expect(webDrivers.length, 2);
final webDriverCurrentUrls =
Set.from(webDrivers.map((webDriver) => webDriver.currentUrl));
expect(webDriverCurrentUrls,
{'https://www.test.com/path/1', 'https://www.test.com/path/2'});
});
test('webDriversForHost refresh session', () async {
final openContexts = {
20000: 'https://www.test.com/path/1',
20001: 'https://www.example.com/path/1',
};
mockAvailableWebDrivers(webDriverHelper, sl4f, portForwarder, openContexts);
final webDrivers =
await webDriverConnector.webDriversForHost('www.test.com');
expect(webDrivers.length, 1);
// Keep port 20000 active
when(sl4f.request('webdriver_facade.GetDevToolsPorts'))
.thenAnswer((_) => Future.value({
'ports': [20000]
}));
// Expire session by throwing NoSuchWindowException.
when(webDrivers.single.window).thenAnswer(
(_) => throw NoSuchWindowException(1, 'Session not displayed'));
when(portForwarder.forwardPort(any)).thenAnswer((invocation) {
final remotePort = invocation.positionalArguments.first;
return Future.value(HostAndPort(testDutAddress, remotePort + 10));
});
when(webDriverHelper.createDriver(any, any)).thenAnswer((invocation) {
WebDriver webDriver = MockWebDriver();
when(webDriver.currentUrl).thenReturn('https://www.test.com/path/2');
return webDriver;
});
final result = await webDriverConnector.webDriversForHost('www.test.com');
expect(result.single.currentUrl, 'https://www.test.com/path/2');
});
test('webDriversForHost no contexts', () async {
mockAvailableWebDrivers(webDriverHelper, sl4f, portForwarder, {});
var webDrivers = await webDriverConnector.webDriversForHost('www.test.com');
expect(webDrivers.length, 0);
});
test('port forwarder chosen correctly', () {
// most targets should use the tcp proxy.
final tcpTargets = ['[::1]', '[fe80::1]', '192.168.0.10', '127.0.0.1'];
for (String tcpTarget in tcpTargets) {
final mockSl4f = MockSl4f();
when(mockSl4f.target).thenReturn(tcpTarget);
final webdriverConnector =
WebDriverConnector('/path/chromedriver', mockSl4f);
expect(webdriverConnector.portForwarder, isA<TcpPortForwarder>());
}
// since chromedriver cannot handle ipv6 zone id, we fallback to ssh port forwarding.
final sshTargets = ['[fe80::1%zone]'];
for (String sshTarget in sshTargets) {
final mockSl4f = MockSl4f();
when(mockSl4f.target).thenReturn(sshTarget);
final webdriverConnector =
WebDriverConnector('/path/chromedriver', mockSl4f);
expect(webdriverConnector.portForwarder, isA<SshPortForwarder>());
}
});
}
/// Set up mocks as if there are chrome contexts with the given ports exposing a url.
void mockAvailableWebDrivers(MockWebDriverHelper webDriverHelper, MockSl4f sl4f,
MockPortForwarder portForwarder, Map<int, String> remotePortToUrl) {
final remotePortList = {'ports': List.from(remotePortToUrl.keys)};
when(sl4f.request('webdriver_facade.GetDevToolsPorts'))
.thenAnswer((_) => Future.value(remotePortList));
// Pretend that open port == remote port + 10, this lets us easily convert
// between the two for mocking.
when(portForwarder.forwardPort(any)).thenAnswer((invocation) {
final remotePort = invocation.positionalArguments.first;
return Future.value(HostAndPort(testDutAddress, remotePort + 10));
});
when(webDriverHelper.createDriver(any, any)).thenAnswer((invocation) {
final accessPoint = invocation.positionalArguments.first;
expect(accessPoint.host, equals(testDutAddress));
final openPort = accessPoint.port;
final remotePort = openPort - 10;
WebDriver webDriver = MockWebDriver();
when(webDriver.currentUrl).thenReturn(remotePortToUrl[remotePort]);
return webDriver;
});
}