test(qml): add spec §4.1 automation objectNames to QML sources

Add the stable automation handles enumerated in spec §4.1, following
the existing sidebar.app.<name> / confirmationDialog.<mode>.<button>
convention: welcomePage.installNow, appManager.{searchField,
category.<name>,emptyView}, appContextMenu root,
addApplicationDialog.{primaryButton,closeButton,errorText,
resolutionBanner}, settings.searchField,
pluginInterface.{call.<method>,result,back}, repositories.{urlField,
addButton,refreshButton,errorBanner,errorDismiss,row.<url>,
removeConfirm.{confirm,cancel}}, and sidebar.buildLabel.

workspace.dock.<name> is deliberately not applied: the dock root's
objectName is pinned to the bare module name by
workspace_area_test.cpp and needs a coordinated rename (recorded as
a finding).
This commit is contained in:
romanzac
2026-08-21 04:30:04 +00:00
parent b4ef120d8a
commit 36f4cf4a1b
8 changed files with 25 additions and 2 deletions
@@ -289,6 +289,7 @@ Dialog {
}
LogosIconButton {
objectName: "addApplicationDialog.closeButton"
iconSource: LogosIcons.close
size: 28
iconSize: 14
@@ -416,6 +417,7 @@ Dialog {
LogosButton {
id: actionButton
objectName: "addApplicationDialog.primaryButton"
Layout.alignment: Qt.AlignVCenter
Layout.preferredWidth: 110
Layout.preferredHeight: 40
@@ -494,6 +496,7 @@ Dialog {
// On failure, show the error here; falls back to a generic line if the
// backend didn't carry a reason.
LogosText {
objectName: "addApplicationDialog.errorText"
Layout.fillWidth: true
Layout.leftMargin: Theme.spacing.large
Layout.rightMargin: Theme.spacing.large
@@ -510,6 +513,7 @@ Dialog {
// Resolver couldn't resolve one or more deps. Surfaced as a
// warning-tone line
LogosText {
objectName: "addApplicationDialog.resolutionBanner"
Layout.fillWidth: true
Layout.leftMargin: Theme.spacing.large
Layout.rightMargin: Theme.spacing.large
@@ -7,6 +7,8 @@ import Basecamp.Backend 1.0
LogosMenu {
id: root
objectName: "appContextMenu"
// Plain object snapshot of the row: name, displayName, repositoryUrl,
// isInstalled, installStage, installStatus, installType. Set via
// openFor() — never bound to a delegate's `model`, which would dangle
@@ -108,6 +108,7 @@ Rectangle {
LogosSearchBar {
id: searchBar
objectName: "appManager.searchField"
Layout.alignment: Qt.AlignRight
Layout.preferredWidth: 605
Layout.minimumWidth: 200
@@ -161,6 +162,7 @@ Rectangle {
delegate: LogosItemDelegate {
id: cell
objectName: "appManager.category." + modelData
width: ListView.view.width
text: modelData
highlighted: ListView.isCurrentItem
@@ -205,6 +207,7 @@ Rectangle {
// AND there are no local-only installed rows to fall back on.
// If either exists, we render the grid instead.
EmptyView {
objectName: "appManager.emptyView"
Layout.fillWidth: true
Layout.fillHeight: true
visible: root.repositories.length === 0
@@ -55,8 +55,9 @@ Item {
spacing: 16
Button {
objectName: "pluginInterface.back"
text: "← Back"
contentItem: LogosText {
text: parent.text
color: "#ffffff"
@@ -159,8 +160,9 @@ Item {
Item { Layout.fillWidth: true }
Button {
objectName: "pluginInterface.call." + (modelData.name || modelData)
text: "Call"
contentItem: LogosText {
text: parent.text
font.pixelSize: Theme.typography.secondaryText
@@ -292,6 +294,7 @@ Item {
clip: true
TextArea {
objectName: "pluginInterface.result"
text: root.resultText
font.pixelSize: 12
font.family: Theme.typography.publicSans
@@ -68,6 +68,7 @@ Item {
}
LogosButton {
objectName: "repositories.refreshButton"
text: root.loading ? qsTr("Refreshing…") : qsTr("Refresh")
enabled: !root.loading
implicitWidth: 120
@@ -78,6 +79,7 @@ Item {
// Error banner — shown until the next successful op.
Rectangle {
objectName: "repositories.errorBanner"
Layout.fillWidth: true
visible: d.lastError.length > 0
radius: Theme.spacing.radiusSmall
@@ -100,6 +102,7 @@ Item {
wrapMode: Text.WordWrap
}
LogosIconButton {
objectName: "repositories.errorDismiss"
iconSource: LogosIcons.close
size: 20
iconSize: 14
@@ -134,12 +137,14 @@ Item {
LogosTextField {
id: urlInput
objectName: "repositories.urlField"
Layout.fillWidth: true
placeholderText: qsTr("https://example.com/logos-repo.json")
text: d.newRepoUrl
onTextChanged: if (text !== d.newRepoUrl) d.newRepoUrl = text
}
LogosButton {
objectName: "repositories.addButton"
text: qsTr("Add")
enabled: d.newRepoUrl.trim().length > 0
implicitWidth: 100
@@ -170,6 +175,7 @@ Item {
readonly property bool isDefault: modelData.isDefault === true
readonly property bool isEnabled: modelData.enabled !== false
objectName: "repositories.row." + url
Layout.fillWidth: true
implicitHeight: rowCol.implicitHeight + Theme.spacing.large * 2
radius: Theme.spacing.radiusLarge
@@ -310,6 +316,7 @@ Item {
leftActions: [
LogosButton {
objectName: "repositories.removeConfirm.cancel"
text: qsTr("Cancel")
onClicked: {
d.pendingRemoveUrl = ""
@@ -320,6 +327,7 @@ Item {
rightActions: [
LogosButton {
objectName: "repositories.removeConfirm.confirm"
text: qsTr("Remove")
variant: LogosButton.Variant.Primary
onClicked: {
+1
View File
@@ -104,6 +104,7 @@ Rectangle {
LogosSearchBar {
id: searchBar
objectName: "settings.searchField"
visible: d.searchable
Layout.alignment: Qt.AlignRight
Layout.preferredWidth: 605
+1
View File
@@ -46,6 +46,7 @@ Item {
}
LogosButton {
objectName: "welcomePage.installNow"
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: Theme.spacing.medium
Layout.preferredWidth: 200
+1
View File
@@ -189,6 +189,7 @@ Control {
// ("Dev build" / "Portable build"). Selectable so the release tag can
// be copied out of the sidebar.
LogosSelectableText {
objectName: "sidebar.buildLabel"
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
horizontalAlignment: TextEdit.AlignHCenter