SPB Git

spb/prisme Public MIT

Navigateur iOS intelligent — chaque page comprise localement avant d'être affichée. SwiftUI · WebKit · Foundation Models, 100% on-device.

Swift 96.7% JavaScript 3.3%
6.7 KB · 187 lines swift
Raw Blame History
1//2//  SmokeTests.swift3//  PrismeUITests4//5//  Author: Simon-Pierre Boucher <contact@spboucher.ai>6//78import XCTest910/// End-to-end smoke tests for the bare browser: address bar intents,11/// search-engine proposals, and actual page loads. Proposals are confirmed12/// by tapping — exactly the designed interaction — because a hardware13/// Return key press can be routed to focused buttons instead of the field.14final class SmokeTests: XCTestCase {1516    override func setUp() {17        continueAfterFailure = false18    }1920    @MainActor21    private func startEditing(_ app: XCUIApplication) -> XCUIElement {22        let compact = app.buttons["addressBar.compact"]23        XCTAssertTrue(compact.waitForExistence(timeout: 5))24        compact.tap()2526        let field = app.textFields["addressBar.field"]27        if !field.waitForExistence(timeout: 3) {28            // A tap landing mid-launch-animation can be swallowed; retry once.29            compact.tap()30        }31        XCTAssertTrue(field.waitForExistence(timeout: 5))32        field.tap()33        return field34    }3536    @MainActor37    func testNavigateToURLLoadsPage() throws {38        let app = XCUIApplication()39        app.launch()4041        let field = startEditing(app)42        field.typeText("example.com")4344        let navigate = app.buttons["proposal.navigate"]45        XCTAssertTrue(navigate.waitForExistence(timeout: 5))46        navigate.tap()4748        XCTAssertTrue(app.webViews.firstMatch.waitForExistence(timeout: 10))49        let pageText = app.webViews.staticTexts["Example Domain"]50        XCTAssertTrue(pageText.waitForExistence(timeout: 20))51        XCTAssertTrue(app.buttons["addressBar.compact"].label.contains("example.com"))52    }5354    @MainActor55    func testSearchProposalsOfferBothEngines() throws {56        let app = XCUIApplication()57        app.launch()5859        let field = startEditing(app)60        field.typeText("chat noir")6162        // Both engines must be proposed on every query.63        XCTAssertTrue(app.buttons["proposal.search.duckDuckGo"].waitForExistence(timeout: 5))64        XCTAssertTrue(app.buttons["proposal.search.google"].exists)65    }6667    @MainActor68    func testReaderSemanticZoomLevels() throws {69        let app = XCUIApplication()70        app.launch()7172        let field = startEditing(app)73        field.typeText("example.com")74        app.buttons["proposal.navigate"].tap()75        XCTAssertTrue(app.webViews.staticTexts["Example Domain"].waitForExistence(timeout: 20))7677        // The understanding strip appears once the page is distilled;78        // it is the main entry into the reader.79        let strip = app.buttons["insight.read"]80        XCTAssertTrue(strip.waitForExistence(timeout: 10))81        attachScreenshot(named: "insight-strip")82        strip.tap()83        XCTAssertTrue(app.buttons["reader.level.Texte"].waitForExistence(timeout: 5))8485        // Full text renders the page's blocks natively.86        XCTAssertTrue(app.staticTexts["Example Domain"].waitForExistence(timeout: 5))87        attachScreenshot(named: "reader-texte")8889        // Outline lists the page's headings.90        app.buttons["reader.level.Plan"].tap()91        XCTAssertTrue(app.staticTexts["Example Domain"].waitForExistence(timeout: 5))9293        // Gist level always resolves — model or deterministic fallback.94        // (The container identifier cascades to the gist's text elements.)95        app.buttons["reader.level.Essentiel"].tap()96        XCTAssertTrue(app.staticTexts["reader.gist"].firstMatch.waitForExistence(timeout: 5))97        attachScreenshot(named: "reader-essentiel")9899        // Closing returns to the raw page (§7).100        app.buttons["reader.close"].tap()101        XCTAssertTrue(app.webViews.firstMatch.waitForExistence(timeout: 5))102    }103104    @MainActor105    func testSemanticHistoryRecallInAddressBar() throws {106        let app = XCUIApplication()107        app.launch()108109        // Visit a page so the history has something to remember.110        var field = startEditing(app)111        field.typeText("example.com")112        app.buttons["proposal.navigate"].tap()113        XCTAssertTrue(app.webViews.staticTexts["Example Domain"].waitForExistence(timeout: 20))114115        // Recording happens shortly after the load settles.116        Thread.sleep(forTimeInterval: 2.5)117118        // From a fresh tab, typing recalls the visited page.119        app.buttons["plus"].tap()120        field = startEditing(app)121        field.typeText("example domain")122123        let recall = app.buttons["proposal.recall"].firstMatch124        XCTAssertTrue(recall.waitForExistence(timeout: 5))125        attachScreenshot(named: "history-recall")126        recall.tap()127128        XCTAssertTrue(app.webViews.staticTexts["Example Domain"].waitForExistence(timeout: 20))129    }130131    @MainActor132    func testStructuredFavoriteFromReaderAppearsInLibrary() throws {133        let app = XCUIApplication()134        app.launch()135136        let field = startEditing(app)137        field.typeText("example.com")138        app.buttons["proposal.navigate"].tap()139        XCTAssertTrue(app.webViews.staticTexts["Example Domain"].waitForExistence(timeout: 20))140141        // Save from the reader: works with or without the local model.142        // (Second reader entry: the affordance in the address bar.)143        XCTAssertTrue(app.buttons["addressBar.reader"].waitForExistence(timeout: 5))144        app.buttons["addressBar.reader"].tap()145        let save = app.buttons["reader.save"]146        XCTAssertTrue(save.waitForExistence(timeout: 5))147        save.tap()148        app.buttons["reader.close"].tap()149150        // The library lists the page as native data.151        app.buttons["books.vertical"].tap()152        XCTAssertTrue(app.buttons["Pages"].waitForExistence(timeout: 5))153        app.buttons["Pages"].tap()154        let favorite = app.buttons["library.favorite"].firstMatch155        XCTAssertTrue(favorite.waitForExistence(timeout: 5))156        XCTAssertTrue(app.staticTexts["Example Domain"].exists)157        attachScreenshot(named: "library-favorite")158    }159160    @MainActor161    private func attachScreenshot(named name: String) {162        let attachment = XCTAttachment(screenshot: XCUIScreen.main.screenshot())163        attachment.name = name164        attachment.lifetime = .keepAlways165        add(attachment)166    }167168    @MainActor169    func testGoogleSearchLoadsGoogle() throws {170        let app = XCUIApplication()171        app.launch()172173        let field = startEditing(app)174        field.typeText("chat noir")175176        let google = app.buttons["proposal.search.google"]177        XCTAssertTrue(google.waitForExistence(timeout: 5))178        google.tap()179180        XCTAssertTrue(app.webViews.firstMatch.waitForExistence(timeout: 10))181        let bar = app.buttons["addressBar.compact"]182        let onGoogle = NSPredicate(format: "label CONTAINS 'google'")183        expectation(for: onGoogle, evaluatedWith: bar)184        waitForExpectations(timeout: 15)185    }186}187