diff --git a/PHP Monitor.xcodeproj/project.pbxproj b/PHP Monitor.xcodeproj/project.pbxproj index 9c0cd7f..74e7fe6 100644 --- a/PHP Monitor.xcodeproj/project.pbxproj +++ b/PHP Monitor.xcodeproj/project.pbxproj @@ -74,6 +74,7 @@ C415D3E92770F692005EF286 /* AppDelegate+InterApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = C415D3E72770F692005EF286 /* AppDelegate+InterApp.swift */; }; C417DC74277614690015E6EE /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = C417DC73277614690015E6EE /* Helpers.swift */; }; C417DC75277614690015E6EE /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = C417DC73277614690015E6EE /* Helpers.swift */; }; + C4181F1128FAF9330042EA28 /* UITestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4181F1028FAF9330042EA28 /* UITestCase.swift */; }; C41C02A627E60D7A009F26CB /* SiteScanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41C02A527E60D7A009F26CB /* SiteScanner.swift */; }; C41C02A927E61A65009F26CB /* ValetSite+Fake.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41C02A827E61A65009F26CB /* ValetSite+Fake.swift */; }; C41C02AA27E61CA3009F26CB /* SiteScanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41C02A527E60D7A009F26CB /* SiteScanner.swift */; }; @@ -163,7 +164,7 @@ C471E79428F9B23B0021E251 /* FileSystemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8900228F0E28800CE5E97 /* FileSystemProtocol.swift */; }; C471E79528F9B2420021E251 /* RealFileSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8900428F0E3D100CE5E97 /* RealFileSystem.swift */; }; C471E7B028F9B4940021E251 /* EmptyTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C471E7AF28F9B4940021E251 /* EmptyTest.swift */; }; - C471E7BF28F9B90F0021E251 /* UI_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C471E7BE28F9B90F0021E251 /* UI_Tests.swift */; }; + C471E7BF28F9B90F0021E251 /* StartupTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C471E7BE28F9B90F0021E251 /* StartupTest.swift */; }; C471E7C928F9BA2F0021E251 /* TestableConfigurations.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40F505428ECA64E004AD45B /* TestableConfigurations.swift */; }; C471E7CA28F9BA480021E251 /* TestableFileSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AD38B128ECD9D300FA8D83 /* TestableFileSystem.swift */; }; C471E7CB28F9BA5B0021E251 /* TestableCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E49DEC28F764A00026AC4E /* TestableCommand.swift */; }; @@ -688,6 +689,7 @@ C415D3E72770F692005EF286 /* AppDelegate+InterApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+InterApp.swift"; sourceTree = ""; }; C4168F4427ADB4A3003B6C39 /* DEVELOPER.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = DEVELOPER.md; sourceTree = ""; }; C417DC73277614690015E6EE /* Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Helpers.swift; sourceTree = ""; }; + C4181F1028FAF9330042EA28 /* UITestCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestCase.swift; sourceTree = ""; }; C41C02A527E60D7A009F26CB /* SiteScanner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SiteScanner.swift; sourceTree = ""; }; C41C02A827E61A65009F26CB /* ValetSite+Fake.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ValetSite+Fake.swift"; sourceTree = ""; }; C41C1B3322B0097F00E7CF16 /* PHP Monitor.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "PHP Monitor.app"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -752,7 +754,7 @@ C471E7AD28F9B4940021E251 /* Feature Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Feature Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; C471E7AF28F9B4940021E251 /* EmptyTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyTest.swift; sourceTree = ""; }; C471E7BC28F9B90F0021E251 /* UI Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "UI Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; - C471E7BE28F9B90F0021E251 /* UI_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UI_Tests.swift; sourceTree = ""; }; + C471E7BE28F9B90F0021E251 /* StartupTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartupTest.swift; sourceTree = ""; }; C473319E2470923A009A0597 /* Localizable.strings */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; path = Localizable.strings; sourceTree = ""; }; C47331A1247093B7009A0597 /* StatusMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusMenu.swift; sourceTree = ""; }; C474B00524C0E98C00066A22 /* LocalNotification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalNotification.swift; sourceTree = ""; }; @@ -1258,7 +1260,8 @@ C471E7BD28F9B90F0021E251 /* ui */ = { isa = PBXGroup; children = ( - C471E7BE28F9B90F0021E251 /* UI_Tests.swift */, + C471E7BE28F9B90F0021E251 /* StartupTest.swift */, + C4181F1028FAF9330042EA28 /* UITestCase.swift */, ); path = ui; sourceTree = ""; @@ -2264,8 +2267,9 @@ C471E7EA28F9BAC30021E251 /* Logger.swift in Sources */, C471E7FB28F9BACE0021E251 /* HomebrewService.swift in Sources */, C471E7EB28F9BAC30021E251 /* Helpers.swift in Sources */, + C4181F1128FAF9330042EA28 /* UITestCase.swift in Sources */, C471E81F28F9BB290021E251 /* NginxConfigurationFile.swift in Sources */, - C471E7BF28F9B90F0021E251 /* UI_Tests.swift in Sources */, + C471E7BF28F9B90F0021E251 /* StartupTest.swift in Sources */, C471E80D28F9BAE80021E251 /* ArrayExtension.swift in Sources */, C471E7CD28F9BA600021E251 /* ShellProtocol.swift in Sources */, C471E7EC28F9BAC30021E251 /* Events.swift in Sources */, diff --git a/tests/ui/StartupTest.swift b/tests/ui/StartupTest.swift new file mode 100644 index 0000000..22008b4 --- /dev/null +++ b/tests/ui/StartupTest.swift @@ -0,0 +1,53 @@ +// +// UI_Tests.swift +// UI Tests +// +// Created by Nico Verbruggen on 14/10/2022. +// Copyright © 2022 Nico Verbruggen. All rights reserved. +// + +import XCTest + +final class StartupTest: UITestCase { + + override func setUpWithError() throws { + continueAfterFailure = false + } + + override func tearDownWithError() throws {} + + func testApplicationCanLaunchWithTestConfigurationAndIdles() throws { + let app = XCUIApplication() + app.launchArguments = ["--configuration:working"] + app.launch() + } + + func testApplicationCanLaunchWithTestConfigurationAndThrowsAlert() throws { + let app = XCUIApplication() + app.launchArguments = ["--configuration:broken"] + app.launch() + + // Dialog 1: "PHP is not correctly installed" + assertAllExist([ + app.dialogs["Notice"], + app.staticTexts["PHP is not correctly installed"], + app.buttons["OK"], + ]) + click(app.buttons["OK"]) + + // Dialog 2: PHP Monitor failed to start + assertAllExist([ + app.dialogs["Notice"], + app.staticTexts["PHP Monitor cannot start due to a problem with your system configuration"], + app.buttons["Retry"], + app.buttons["Quit"] + ]) + click(app.buttons["Retry"]) + + // Dialog 1 again + assertExists(app.staticTexts["PHP is not correctly installed"]) + + // At this point, we can terminate the test + app.terminate() + } +} diff --git a/tests/ui/UITestCase.swift b/tests/ui/UITestCase.swift new file mode 100644 index 0000000..f8520dc --- /dev/null +++ b/tests/ui/UITestCase.swift @@ -0,0 +1,30 @@ +// +// UITestCase.swift +// UI Tests +// +// Created by Nico Verbruggen on 15/10/2022. +// Copyright © 2022 Nico Verbruggen. All rights reserved. +// + +import XCTest + +class UITestCase: XCTestCase { + + /** Checks if a single element exists. */ + public func assertExists(_ element: XCUIElement, _ timeout: TimeInterval = 0.05) { + XCTAssert(element.waitForExistence(timeout: timeout)) + } + + /** Checks if all elements exist. */ + public func assertAllExist(_ elements: [XCUIElement], _ timeout: TimeInterval = 0.05) { + for element in elements { + XCTAssert(element.waitForExistence(timeout: timeout)) + } + } + + /** Clicks on a given element. */ + public func click(_ element: XCUIElement) { + element.click() + } + +} diff --git a/tests/ui/UI_Tests.swift b/tests/ui/UI_Tests.swift deleted file mode 100644 index f929869..0000000 --- a/tests/ui/UI_Tests.swift +++ /dev/null @@ -1,41 +0,0 @@ -// -// UI_Tests.swift -// UI Tests -// -// Created by Nico Verbruggen on 14/10/2022. -// Copyright © 2022 Nico Verbruggen. All rights reserved. -// - -import XCTest - -final class UI_Tests: XCTestCase { - - override func setUpWithError() throws { - continueAfterFailure = false - } - - override func tearDownWithError() throws {} - - func testApplicationCanLaunchWithTestConfigurationAndIdles() throws { - // UI tests must launch the application that they test. - let app = XCUIApplication() - app.launchArguments = ["--configuration:working"] - app.launch() - // XCTAssert(app.dialogs["Notice"].waitForExistence(timeout: 5)) - sleep(10) - } - - func testApplicationCanLaunchWithTestConfigurationAndThrowsAlert() throws { - // UI tests must launch the application that they test. - let app = XCUIApplication() - app.launchArguments = ["--configuration:broken"] - app.launch() - XCTAssert(app.dialogs["Notice"].waitForExistence(timeout: 5)) - app.buttons["OK"].click() - XCTAssert(app.dialogs["Notice"].waitForExistence(timeout: 5)) - XCTAssert(app.buttons["Quit"].waitForExistence(timeout: 1)) - // If this UI test presses the "Quit" button, the test takes forever - // because Xcode will attempt to figure out if the app closed correctly. - app.terminate() - } -}