Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ class A11yOnboardingTests: BaseTestCase {
return "\(AccessibilityIdentifiers.Onboarding.onboarding)\(currentScreen)"
}

override func setUp() {
override func setUp() async throws {
launchArguments = [LaunchArguments.ClearProfile,
LaunchArguments.DisableAnimations,
LaunchArguments.SkipSplashScreenExperiment]
currentScreen = 0
super.setUp()
try await super.setUp()
}

override func tearDown() {
override func tearDown() async throws {
app.terminate()
super.tearDown()
try await super.tearDown()
}

func testA11yFirstRunTour() throws {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/

import XCTest

@MainActor
class A11yUtils: XCTestCase {
public struct MissingAccessibilityElement {
public let elementType: String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ class ActivityStreamTest: FeatureFlaggedTestBase {
let testWithDB = ["testTopSites2Add", "testTopSitesRemoveAllExceptDefaultClearPrivateData"]
// Using the DDDBBs created for these tests containing enough entries for the tests that used them listed above
let pagesVisited = "browserActivityStreamPages-places.db"
override func setUp() {

override func setUp() async throws {
// Test name looks like: "[Class testFunc]", parse out the function name
let parts = name.replacingOccurrences(of: "]", with: "").split(separator: " ")
let key = String(parts[1])
Expand All @@ -41,16 +42,17 @@ class ActivityStreamTest: FeatureFlaggedTestBase {
}
launchArguments.append(LaunchArguments.SkipAddingGoogleTopSite)
launchArguments.append(LaunchArguments.SkipSponsoredShortcuts)
super.setUp()
try await super.setUp()
topSites = TopSitesScreen(app: app)
contextMenu = ContextMenuScreen(app: app)
tabTray = TabTrayScreen(app: app)
browser = BrowserScreen(app: app)
toolbar = ToolbarScreen(app: app)
}
override func tearDown() {

override func tearDown() async throws {
XCUIDevice.shared.orientation = .portrait
super.tearDown()
try await super.tearDown()
}

// https://mozilla.testrail.io/index.php?/cases/view/2273342
Expand Down
18 changes: 10 additions & 8 deletions firefox-ios/firefox-ios-tests/Tests/XCUITests/BaseTestCase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import Shared
let page1 = "http://localhost:\(serverPort)/test-fixture/find-in-page-test.html"
let page2 = "http://localhost:\(serverPort)/test-fixture/test-example.html"
let serverPort = ProcessInfo.processInfo.environment["WEBSERVER_PORT"] ?? "\(Int.random(in: 1025..<65000))"
@MainActor
let urlBarAddress = XCUIApplication().textFields[AccessibilityIdentifiers.Browser.AddressToolbar.searchTextField]
@MainActor
let homepageSearchBar = XCUIApplication().cells[AccessibilityIdentifiers.FirefoxHomepage.SearchBar.itemCell]

func path(forTestPage page: String) -> String {
Expand Down Expand Up @@ -107,16 +109,16 @@ class BaseTestCase: XCTestCase {
}
}

override func setUp() {
super.setUp()
override func setUp() async throws {
try await super.setUp()
continueAfterFailure = false
setUpApp()
setUpScreenGraph()
}

override func tearDown() {
override func tearDown() async throws {
app.terminate()
super.tearDown()
try await super.tearDown()
}

var skipPlatform: Bool {
Expand Down Expand Up @@ -503,19 +505,19 @@ class BaseTestCase: XCTestCase {
}

class IpadOnlyTestCase: BaseTestCase {
override func setUp() {
override func setUp() async throws {
specificForPlatform = .pad
if iPad() {
super.setUp()
await super.setUp()
}
Comment on lines +508 to 512
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# First, find and read the specific file
find . -name "BaseTestCase.swift" -path "*XCUITests*" | head -5

Repository: qodo-benchmark/firefox-ios-combined-coderabbit

Length of output: 156


🏁 Script executed:

# Check file size first
wc -l firefox-ios/firefox-ios-tests/Tests/XCUITests/BaseTestCase.swift 2>/dev/null || find . -name "BaseTestCase.swift" -type f | xargs wc -l

Repository: qodo-benchmark/firefox-ios-combined-coderabbit

Length of output: 158


🏁 Script executed:

# Read the relevant section around lines 508-512
sed -n '500,520p' firefox-ios/firefox-ios-tests/Tests/XCUITests/BaseTestCase.swift 2>/dev/null || find . -name "BaseTestCase.swift" -type f -exec sed -n '500,520p' {} \;

Repository: qodo-benchmark/firefox-ios-combined-coderabbit

Length of output: 639


🏁 Script executed:

# Search for the setUp method definition and its class hierarchy
rg -A 5 "override func setUp\(\) async throws" firefox-ios/firefox-ios-tests/Tests/XCUITests/ 2>/dev/null || rg -A 5 "func setUp.*async.*throws"

Repository: qodo-benchmark/firefox-ios-combined-coderabbit

Length of output: 22447


🏁 Script executed:

# Check the parent class to verify setUp() signature
rg -B 5 "class BaseTestCase" firefox-ios/firefox-ios-tests/Tests/XCUITests/BaseTestCase.swift 2>/dev/null || rg "class BaseTestCase"

Repository: qodo-benchmark/firefox-ios-combined-coderabbit

Length of output: 219


Add missing try keyword on throwing async super call.
super.setUp() is async throws; the call requires try.

Suggested fix
-        if iPad() {
-            await super.setUp()
-        }
+        if iPad() {
+            try await super.setUp()
+        }
🤖 Prompt for AI Agents
In `@firefox-ios/firefox-ios-tests/Tests/XCUITests/BaseTestCase.swift` around
lines 508 - 512, The overridden async test setup calls super.setUp() without the
required try; update the call in override func setUp() async throws so the
throwing async call uses try await (i.e., replace await super.setUp() with try
await super.setUp()) to properly propagate errors from the superclass setup.

}
}

class IphoneOnlyTestCase: BaseTestCase {
override func setUp() {
override func setUp() async throws {
specificForPlatform = .phone
if !iPad() {
super.setUp()
try await super.setUp()
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ class BookmarksTests: FeatureFlaggedTestBase {
private var homepageSettingsScreen: HomepageSettingsScreen!
private var firefoxHomeScreen: FirefoxHomePageScreen!

override func setUp() {
super.setUp()
override func setUp() async throws {
try await super.setUp()
topSitesScreen = TopSitesScreen(app: app)
browserScreen = BrowserScreen(app: app)
toolbarScreen = ToolbarScreen(app: app)
Expand All @@ -28,9 +28,9 @@ class BookmarksTests: FeatureFlaggedTestBase {
firefoxHomeScreen = FirefoxHomePageScreen(app: app)
}

override func tearDown() {
override func tearDown() async throws {
XCUIDevice.shared.orientation = .portrait
super.tearDown()
try await super.tearDown()
}

private func checkBookmarked() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ class BrowsingPDFTests: BaseTestCase {
private var contextMenu: ContextMenuScreen!
private var library: LibraryScreen!

override func setUp() {
override func setUp() async throws {
// Test name looks like: "[Class testFunc]", parse out the function name
super.setUp()
try await super.setUp()
topSites = TopSitesScreen(app: app)
contextMenu = ContextMenuScreen(app: app)
pdf = PDFScreen(app: app)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ class O_AddressesTests: BaseTestCase {
private var settingsScreen: SettingScreen!
private var browserScreen: BrowserScreen!

override func setUp() {
super.setUp()
override func setUp() async throws {
try await super.setUp()

if #available(iOS 16, *) {
if !name.contains("testAddressOptionIsAvailableInSettingsMenu") {
navigator.nowAt(NewTabScreen)
Expand All @@ -34,13 +35,13 @@ class O_AddressesTests: BaseTestCase {
browserScreen = BrowserScreen(app: app)
}

override func tearDown() {
override func tearDown() async throws {
if name.contains("testAddressOptionIsAvailableInSettingsMenu") {
switchThemeToDarkOrLight(theme: "Light")
XCUIDevice.shared.orientation = .portrait
}
app.terminate()
super.tearDown()
try await super.tearDown()
}

// https://mozilla.testrail.io/index.php?/cases/view/2618637
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ final class CookiePersistenceTests: BaseTestCase {
let cookieSiteURL = "http://localhost:\(serverPort)/test-fixture/test-cookie-store.html"
let topSitesTitle = ["Facebook", "YouTube", "Wikipedia"]

override func setUp() {
override func setUp() async throws {
// Fresh install the app
// removeApp() does not work on iOS 15 and 16 intermittently
if #available(iOS 17, *) {
removeApp()
}

// The app is correctly installed
super.setUp()
try await super.setUp()
}

func testCookiePersistenceBasic() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class DatabaseFixtureTest: BaseTestCase {
"testHistoryDatabaseFixture": "testHistoryDatabase100-places.db"
]

override func setUp() {
override func setUp() async throws {
// Test name looks like: "[Class testFunc]", parse out the function name
let parts = name.replacingOccurrences(of: "]", with: "").split(separator: " ")
let key = String(parts[1])
Expand All @@ -21,7 +21,7 @@ class DatabaseFixtureTest: BaseTestCase {
LaunchArguments.LoadDatabasePrefix + fixtures[key]!,
LaunchArguments.SkipContextualHints,
LaunchArguments.DisableAnimations]
super.setUp()
try await super.setUp()
}

// https://mozilla.testrail.io/index.php?/cases/view/2458579
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,10 @@ class DesktopModeTestsIphone: BaseTestCase {
var toolbarScreen: ToolbarScreen!
var mainMenuScreen: MainMenuScreen!

override func setUp() {
override func setUp() async throws {
specificForPlatform = .phone
if !iPad() {
super.setUp()
try await super.setUp()
}
browserScreen = BrowserScreen(app: app)
toolbarScreen = ToolbarScreen(app: app)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import XCTest

class DisplaySettingTests: BaseTestCase {
override func setUp() {
override func setUp() async throws {
// Fresh install the app
// removeApp() does not work on iOS 15 and 16 intermittently
if name.contains("testCheckDisplaySettingsDefault") {
Expand All @@ -14,7 +14,7 @@ class DisplaySettingTests: BaseTestCase {
}
}
// The app is correctly installed
super.setUp()
try await super.setUp()
}

// https://mozilla.testrail.io/index.php?/cases/view/2337485
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class DomainAutocompleteTests: BaseTestCase {
// This DB contains 3 entries mozilla.com/github.com/git.es
let historyDB = "browserAutocomplete-places.db"

override func setUp() {
override func setUp() async throws {
// Test name looks like: "[Class testFunc]", parse out the function name
let parts = name.replacingOccurrences(of: "]", with: "").split(separator: " ")
let key = String(parts[1])
Expand All @@ -41,7 +41,7 @@ class DomainAutocompleteTests: BaseTestCase {
LaunchArguments.SkipContextualHints,
LaunchArguments.DisableAnimations]
}
super.setUp()
try await super.setUp()
}

// https://mozilla.testrail.io/index.php?/cases/view/2334558
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ class DragAndDropTestIpad: IpadOnlyTestCase {
// This DDBB contains those 4 websites listed in the name
let historyAndBookmarksDB = "browserYoutubeTwitterMozillaExample-places.db"

override func setUp() {
override func setUp() async throws {
// Test name looks like: "[Class testFunc]", parse out the function name
let parts = name.replacingOccurrences(of: "]", with: "").split(separator: " ")
let key = String(parts[1])
Expand All @@ -304,12 +304,12 @@ class DragAndDropTestIpad: IpadOnlyTestCase {
LaunchArguments.SkipContextualHints,
LaunchArguments.DisableAnimations]
}
super.setUp()
try await super.setUp()
}

override func tearDown() {
override func tearDown() async throws {
XCUIDevice.shared.orientation = UIDeviceOrientation.portrait
super.tearDown()
try await super.tearDown()
}

// https://mozilla.testrail.io/index.php?/cases/view/2307024
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
import XCTest

class EngagementNotificationTests: BaseTestCase {
override func setUp() {
override func setUp() async throws {
// Fresh install the app
// removeApp() does not work on iOS 15 and 16 intermittently
if #available(iOS 17, *) {
removeApp()
}
// The app is correctly installed
super.setUp()
try await super.setUp()
}

// https://mozilla.testrail.io/index.php?/cases/view/2307101
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ class FeatureFlaggedTestSuite: FeatureFlaggedTestBase {
addLaunchArgument(jsonFileName: jsonFileName, featureName: featureName)
}

override func setUp() {
override func setUp() async throws {
continueAfterFailure = false
setUpExperimentVariables()
setUpApp()
setUpExperimentVariables()
setUpLaunchArguments()
Comment on lines +46 to 50
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Initialize experiment variables before building launch arguments.

setUpApp() uses jsonFileName/featureName (Line 42–44), but setUpExperimentVariables() now runs after it (Line 49). Since those are IUOs meant to be set in setUpExperimentVariables(), this can crash or miss arguments.

💡 Suggested fix (restore safe ordering)
 override func setUp() async throws {
     continueAfterFailure = false
-    setUpApp()
-    setUpExperimentVariables()
+    setUpExperimentVariables()
+    setUpApp()
     setUpLaunchArguments()
     setUpScreenGraph()
 }
🤖 Prompt for AI Agents
In `@firefox-ios/firefox-ios-tests/Tests/XCUITests/FeatureFlaggedTestBase.swift`
around lines 46 - 50, The setup ordering is incorrect: move the call to
setUpExperimentVariables() to run before setUpApp() and setUpLaunchArguments()
inside override func setUp() so the implicitly unwrapped optionals jsonFileName
and featureName are initialized prior to being used by setUpApp() (and before
building launch arguments in setUpLaunchArguments()); update the sequence in
setUp() to call setUpExperimentVariables() first, then setUpApp(), then
setUpLaunchArguments() to prevent crashes or missing arguments.

setUpScreenGraph()
}
Comment on lines +46 to 52
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find . -name "*.swift" | head -20

Repository: qodo-benchmark/firefox-ios-combined-coderabbit

Length of output: 1292


🏁 Script executed:

git ls-files | grep -i test | grep -i swift | head -20

Repository: qodo-benchmark/firefox-ios-combined-coderabbit

Length of output: 1296


🏁 Script executed:

cat -n firefox-ios/firefox-ios-tests/Tests/XCUITests/FeatureFlaggedTestBase.swift | head -80

Repository: qodo-benchmark/firefox-ios-combined-coderabbit

Length of output: 2901


🏁 Script executed:

# Find the parent class of FeatureFlaggedTestBase
rg "class FeatureFlaggedTestBase" -A 2

Repository: qodo-benchmark/firefox-ios-combined-coderabbit

Length of output: 472


🏁 Script executed:

# Search for BaseTestCase definition
rg "class BaseTestCase" -A 20

Repository: qodo-benchmark/firefox-ios-combined-coderabbit

Length of output: 6392


🏁 Script executed:

cat -n firefox-ios/firefox-ios-tests/Tests/XCUITests/BaseTestCase.swift | head -150

Repository: qodo-benchmark/firefox-ios-combined-coderabbit

Length of output: 7051


🏁 Script executed:

# Check how XCTestCase.setUp is typically used
rg "override func setUp" firefox-ios/firefox-ios-tests/Tests/XCUITests/ -A 5 | head -100

Repository: qodo-benchmark/firefox-ios-combined-coderabbit

Length of output: 9898


🏁 Script executed:

# Look for other test classes that extend BaseTestCase
rg "class.*: BaseTestCase" firefox-ios/firefox-ios-tests/Tests/XCUITests/

Repository: qodo-benchmark/firefox-ios-combined-coderabbit

Length of output: 6767


Refactor to call try await super.setUp() rather than duplicating parent setup logic.

FeatureFlaggedTestSuite.setUp() bypasses the entire parent initialization chain, inconsistent with BaseTestCase and the broader test codebase. While the intentional delay of app.launch() (via FeatureFlaggedTestBase's setUpApp override) is valid, this should not require skipping XCTestCase.setUp(). Refactor to call try await super.setUp() first, then override only what's needed for experiment setup.

🤖 Prompt for AI Agents
In `@firefox-ios/firefox-ios-tests/Tests/XCUITests/FeatureFlaggedTestBase.swift`
around lines 46 - 52, The override of setUp() in FeatureFlaggedTestBase
duplicates parent initialization; change it to call try await super.setUp() at
the top of FeatureFlaggedTestBase.setUp(), keep continueAfterFailure = false if
needed, then only perform test-specific setup like setUpExperimentVariables()
and setUpScreenGraph(); remove the direct calls to setUpApp() and
setUpLaunchArguments() here since the base class (and FeatureFlaggedTestBase's
setUpApp override) should manage app launch timing and launch args.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Foundation
import MappaMundi
import XCTest

@MainActor
func createScreenGraph(for test: XCTestCase, with app: XCUIApplication) -> MMScreenGraph<FxUserState> {
let map = MMScreenGraph(for: test, with: FxUserState.self)

Expand Down Expand Up @@ -123,31 +124,38 @@ let allHomePanels = [
LibraryPanel_Downloads
]

@MainActor
let iOS_Settings = XCUIApplication(bundleIdentifier: "com.apple.Preferences")
@MainActor
let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")

@MainActor
func navigationControllerBackAction(for app: XCUIApplication) -> () -> Void {
return {
app.navigationBars.element(boundBy: 0).buttons.element(boundBy: 0).waitAndTap()
}
}

@MainActor
func cancelBackAction(for app: XCUIApplication) -> () -> Void {
return {
app.otherElements["PopoverDismissRegion"].waitAndTap()
}
}

@MainActor
func dismissContextMenuAction(app: XCUIApplication) -> () -> Void {
return {
app.coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.25)).tap()
}
}

@MainActor
func select(rows: Int, in app: XCUIApplication) {
app.staticTexts[String(rows)].firstMatch.waitAndTap()
}

@MainActor
func type(text: String, in app: XCUIApplication) {
text.forEach { char in
app.keys[String(char)].waitAndTap()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class HistoryTests: BaseTestCase {
var browserScreen: BrowserScreen!
var historyScreen: HistoryScreen!

override func setUp() {
override func setUp() async throws {
// Test name looks like: "[Class testFunc]", parse out the function name
let parts = name.replacingOccurrences(of: "]", with: "").split(separator: " ")
let key = String(parts[1])
Expand All @@ -57,7 +57,7 @@ class HistoryTests: BaseTestCase {
LaunchArguments.SkipContextualHints,
LaunchArguments.DisableAnimations]
}
super.setUp()
try await super.setUp()
toolbarScreen = ToolbarScreen(app: app)
settingScreen = SettingScreen(app: app)
browserScreen = BrowserScreen(app: app)
Expand Down
Loading