236 lines
9.3 KiB
Swift
236 lines
9.3 KiB
Swift
import XCTest
|
|
import Foundation
|
|
|
|
private func browserImportPollUntil(
|
|
timeout: TimeInterval,
|
|
pollInterval: TimeInterval = 0.05,
|
|
condition: () -> Bool
|
|
) -> Bool {
|
|
let start = ProcessInfo.processInfo.systemUptime
|
|
while true {
|
|
if condition() {
|
|
return true
|
|
}
|
|
if (ProcessInfo.processInfo.systemUptime - start) >= timeout {
|
|
return false
|
|
}
|
|
RunLoop.current.run(until: Date().addingTimeInterval(pollInterval))
|
|
}
|
|
}
|
|
|
|
final class BrowserImportProfilesUITests: XCTestCase {
|
|
private var capturePath = ""
|
|
|
|
override func setUp() {
|
|
super.setUp()
|
|
continueAfterFailure = false
|
|
capturePath = "/tmp/cmux-ui-test-browser-import-\(UUID().uuidString).json"
|
|
try? FileManager.default.removeItem(atPath: capturePath)
|
|
}
|
|
|
|
func testMultipleSourceProfilesDefaultToSeparateDestinations() throws {
|
|
let app = launchApp()
|
|
|
|
app.buttons["Next"].click()
|
|
app.buttons["Next"].click()
|
|
|
|
XCTAssertTrue(
|
|
app.radioButtons["Separate profiles"].waitForExistence(timeout: 5.0),
|
|
"Expected Step 3 to show the separate-profiles default"
|
|
)
|
|
XCTAssertTrue(app.radioButtons["Merge into one"].exists)
|
|
XCTAssertTrue(app.popUpButtons["BrowserImportDestinationPopup-you"].exists)
|
|
XCTAssertTrue(app.popUpButtons["BrowserImportDestinationPopup-austin"].exists)
|
|
|
|
app.buttons["Start Import"].click()
|
|
|
|
let capture = try XCTUnwrap(waitForCapturedSelection(timeout: 5.0))
|
|
XCTAssertEqual(capture["mode"] as? String, "separateProfiles")
|
|
XCTAssertEqual(capture["scope"] as? String, "cookiesAndHistory")
|
|
|
|
let entries = try XCTUnwrap(capture["entries"] as? [[String: Any]])
|
|
XCTAssertEqual(entries.count, 2)
|
|
XCTAssertEqual(entries[0]["sourceProfiles"] as? [String], ["You"])
|
|
XCTAssertEqual(entries[0]["destinationKind"] as? String, "create")
|
|
XCTAssertEqual(entries[0]["destinationName"] as? String, "You")
|
|
XCTAssertEqual(entries[1]["sourceProfiles"] as? [String], ["austin"])
|
|
XCTAssertEqual(entries[1]["destinationKind"] as? String, "create")
|
|
XCTAssertEqual(entries[1]["destinationName"] as? String, "austin")
|
|
}
|
|
|
|
func testMergeModeCapturesSingleMergedDestination() throws {
|
|
let app = launchApp()
|
|
|
|
app.buttons["Next"].click()
|
|
app.buttons["Next"].click()
|
|
|
|
let mergeRadio = app.radioButtons["Merge into one"]
|
|
XCTAssertTrue(mergeRadio.waitForExistence(timeout: 5.0))
|
|
mergeRadio.click()
|
|
|
|
XCTAssertTrue(
|
|
app.popUpButtons["BrowserImportDestinationPopup-merge"].waitForExistence(timeout: 5.0),
|
|
"Expected merge mode to show the single destination popup"
|
|
)
|
|
|
|
app.buttons["Start Import"].click()
|
|
|
|
let capture = try XCTUnwrap(waitForCapturedSelection(timeout: 5.0))
|
|
XCTAssertEqual(capture["mode"] as? String, "mergeIntoOne")
|
|
|
|
let entries = try XCTUnwrap(capture["entries"] as? [[String: Any]])
|
|
XCTAssertEqual(entries.count, 1)
|
|
XCTAssertEqual(entries[0]["sourceProfiles"] as? [String], ["You", "austin"])
|
|
XCTAssertEqual(entries[0]["destinationKind"] as? String, "existing")
|
|
XCTAssertEqual(entries[0]["destinationName"] as? String, "Default")
|
|
}
|
|
|
|
func testAdditionalDataSelectionCapturesEverythingScope() throws {
|
|
let app = launchApp()
|
|
|
|
app.buttons["Next"].click()
|
|
app.buttons["Next"].click()
|
|
|
|
let cookiesCheckbox = app.checkBoxes["BrowserImportCookiesCheckbox"]
|
|
XCTAssertTrue(cookiesCheckbox.waitForExistence(timeout: 5.0))
|
|
cookiesCheckbox.click()
|
|
|
|
let historyCheckbox = app.checkBoxes["BrowserImportHistoryCheckbox"]
|
|
XCTAssertTrue(historyCheckbox.waitForExistence(timeout: 5.0))
|
|
historyCheckbox.click()
|
|
|
|
let additionalDataCheckbox = app.checkBoxes["BrowserImportAdditionalDataCheckbox"]
|
|
XCTAssertTrue(
|
|
additionalDataCheckbox.waitForExistence(timeout: 5.0),
|
|
"Expected Step 3 to expose the additional data checkbox"
|
|
)
|
|
additionalDataCheckbox.click()
|
|
|
|
app.buttons["Start Import"].click()
|
|
|
|
let capture = try XCTUnwrap(waitForCapturedSelection(timeout: 5.0))
|
|
XCTAssertEqual(capture["scope"] as? String, "everything")
|
|
}
|
|
|
|
func testBlankBrowserImportHintCanOpenBrowserSettings() {
|
|
let app = launchAppForBlankImportHint()
|
|
|
|
let settingsButton = app.buttons["BrowserImportHintSettingsButton"]
|
|
XCTAssertTrue(settingsButton.waitForExistence(timeout: 5.0))
|
|
settingsButton.click()
|
|
|
|
let importSection = app.otherElements["SettingsBrowserImportSection"]
|
|
XCTAssertTrue(
|
|
importSection.waitForExistence(timeout: 5.0),
|
|
"Expected Browser Settings to scroll to the import section"
|
|
)
|
|
|
|
let chooseButton = app.buttons["SettingsBrowserImportChooseButton"]
|
|
XCTAssertTrue(
|
|
chooseButton.waitForExistence(timeout: 5.0),
|
|
"Expected Browser Settings to expose the import actions"
|
|
)
|
|
XCTAssertTrue(
|
|
browserImportPollUntil(timeout: 5.0) {
|
|
importSection.isHittable && chooseButton.isHittable
|
|
},
|
|
"Expected Browser Settings to scroll directly to the import controls"
|
|
)
|
|
}
|
|
|
|
func testBlankBrowserImportHintCanBeDismissed() {
|
|
let app = launchAppForBlankImportHint()
|
|
|
|
let dismissButton = app.buttons["BrowserImportHintDismissButton"]
|
|
XCTAssertTrue(dismissButton.waitForExistence(timeout: 5.0))
|
|
dismissButton.click()
|
|
|
|
XCTAssertTrue(
|
|
browserImportPollUntil(timeout: 2.0) { !dismissButton.exists },
|
|
"Expected the blank-tab import hint to disappear after dismissal"
|
|
)
|
|
}
|
|
|
|
private func launchApp() -> XCUIApplication {
|
|
let app = XCUIApplication()
|
|
app.launchEnvironment["CMUX_UI_TEST_MODE"] = "1"
|
|
app.launchEnvironment["CMUX_UI_TEST_BROWSER_IMPORT_FIXTURE"] = #"{"browserName":"Helium","profiles":["You","austin"]}"#
|
|
app.launchEnvironment["CMUX_UI_TEST_BROWSER_IMPORT_DESTINATIONS"] = #"["Default"]"#
|
|
app.launchEnvironment["CMUX_UI_TEST_BROWSER_IMPORT_MODE"] = "capture-only"
|
|
app.launchEnvironment["CMUX_UI_TEST_BROWSER_IMPORT_CAPTURE_PATH"] = capturePath
|
|
app.launchEnvironment["CMUX_UI_TEST_BROWSER_IMPORT_HINT_VARIANT"] = "inlineStrip"
|
|
app.launchEnvironment["CMUX_UI_TEST_BROWSER_IMPORT_HINT_SHOW"] = "1"
|
|
app.launchEnvironment["CMUX_UI_TEST_BROWSER_IMPORT_HINT_DISMISSED"] = "0"
|
|
app.launchEnvironment["CMUX_UI_TEST_BROWSER_IMPORT_HINT_OPEN_BLANK_BROWSER"] = "1"
|
|
launchAndActivate(app)
|
|
openImportWizardFromBlankImportHint(app)
|
|
return app
|
|
}
|
|
|
|
private func launchAppForBlankImportHint() -> XCUIApplication {
|
|
let app = XCUIApplication()
|
|
app.launchEnvironment["CMUX_UI_TEST_MODE"] = "1"
|
|
app.launchEnvironment["CMUX_UI_TEST_BROWSER_IMPORT_HINT_VARIANT"] = "inlineStrip"
|
|
app.launchEnvironment["CMUX_UI_TEST_BROWSER_IMPORT_HINT_SHOW"] = "1"
|
|
app.launchEnvironment["CMUX_UI_TEST_BROWSER_IMPORT_HINT_DISMISSED"] = "0"
|
|
app.launchEnvironment["CMUX_UI_TEST_BROWSER_IMPORT_HINT_OPEN_BLANK_BROWSER"] = "1"
|
|
launchAndActivate(app)
|
|
waitForBlankImportHint(app)
|
|
return app
|
|
}
|
|
|
|
private func waitForImportWizard(_ app: XCUIApplication) {
|
|
let wizardOpened = browserImportPollUntil(timeout: 5.0) {
|
|
app.buttons["Next"].exists || app.windows["Import Browser Data"].exists
|
|
}
|
|
XCTAssertTrue(wizardOpened, "Expected the import wizard to open")
|
|
}
|
|
|
|
private func waitForBlankImportHint(_ app: XCUIApplication) {
|
|
let hintOpened = browserImportPollUntil(timeout: 5.0) {
|
|
app.buttons["BrowserImportHintImportButton"].exists
|
|
}
|
|
XCTAssertTrue(hintOpened, "Expected the blank browser import hint to appear")
|
|
}
|
|
|
|
private func openImportWizardFromBlankImportHint(_ app: XCUIApplication) {
|
|
waitForBlankImportHint(app)
|
|
|
|
let importButton = app.buttons["BrowserImportHintImportButton"]
|
|
XCTAssertTrue(importButton.waitForExistence(timeout: 5.0))
|
|
importButton.click()
|
|
|
|
waitForImportWizard(app)
|
|
}
|
|
|
|
private func waitForCapturedSelection(timeout: TimeInterval) -> [String: Any]? {
|
|
let url = URL(fileURLWithPath: capturePath)
|
|
let foundCapture = browserImportPollUntil(timeout: timeout) {
|
|
if let data = try? Data(contentsOf: url),
|
|
let object = try? JSONSerialization.jsonObject(with: data) as? [String: Any] {
|
|
return !object.isEmpty
|
|
}
|
|
return false
|
|
}
|
|
if foundCapture,
|
|
let data = try? Data(contentsOf: url),
|
|
let object = try? JSONSerialization.jsonObject(with: data) as? [String: Any] {
|
|
return object
|
|
}
|
|
return nil
|
|
}
|
|
|
|
private func launchAndActivate(_ app: XCUIApplication, activateTimeout: TimeInterval = 2.0) {
|
|
app.launch()
|
|
let activated = browserImportPollUntil(timeout: activateTimeout) {
|
|
guard app.state != .runningForeground else {
|
|
return true
|
|
}
|
|
app.activate()
|
|
return app.state == .runningForeground
|
|
}
|
|
if !activated {
|
|
app.activate()
|
|
}
|
|
}
|
|
}
|