Skip to content

Commit 7077b9a

Browse files
Merge pull request #3 from browserstack/DEVA11Y-128-2
[JIRA DEVA11Y-128] Added user-setup scripts
1 parent ca151ac commit 7077b9a

14 files changed

+756
-47
lines changed

README.md

Lines changed: 96 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,16 @@ AccessibilityDevTools enables static accessibility linting directly inside Xcode
1010
* 🛠 **Inline errors inside Xcode** with remediation guidance
1111
***Runs during build** using the SPM command plugin
1212

13+
---
14+
## Supported projects types
15+
1. Projects created with Swift package manager
16+
2. Projects created with XCode
17+
1318
---
1419
## Authentication
1520
1. Log in to your BrowserStack account or [sign up](https://www.browserstack.com/users/sign_in) if you don’t have an account.
1621
2. Obtain your **Username** and **Access Key** from the [Account & Profile section](https://www.browserstack.com/accounts/profile/details) section on the dashboard.
17-
![Account & Profile section](./resources/a31150e8-6beb-4541-bc2a-e1d9f03e431d.png "Account & Profile section")
22+
![Account & Profile section](./resources/accounts.png "Account & Profile section")
1823

1924
3. Set the following environment variables using the **Username** and **Access Key** you obtained in step 2.
2025
* `BROWSERSTACK_USERNAME`
@@ -38,79 +43,123 @@ AccessibilityDevTools enables static accessibility linting directly inside Xcode
3843

3944
---
4045
## Installation
41-
### SwiftPM Projects
42-
For SwiftPM projects, you can use the SPM `command plugin` for Accessibility DevTools.
46+
### 1. Projects created with XCode
47+
> Note: XCode projects don’t have a Package.swift file. However, the script will manage this for you. If you prefer not to do this or face any issues, you can use our CLI for linting instead.
4348

44-
**Add plugin in your `Package.swift`**
49+
#### Clone Script
50+
Run the following command at the <span style="color:red">root of your repository</span>
4551

46-
Edit the `Project.swift` to include following code. Specifically, these two things to be added
52+
Zsh
53+
```zsh
54+
curl -L -o browserstack-a11y-scan-spm.sh "https://raw.githubusercontent.com/browserstack/AccessibilityDevTools/refs/heads/main/scripts/zsh/spm.sh" && chmod 0775 browserstack-a11y-scan-spm.sh
55+
```
4756

48-
* Add `AccessibilityDevTools` as a package under dependencies
57+
Bash
58+
```bash
59+
curl -L -o browserstack-a11y-scan-spm.sh "https://raw.githubusercontent.com/browserstack/AccessibilityDevTools/refs/heads/main/scripts/bash/spm.sh" && chmod 0775 browserstack-a11y-scan-spm.sh
60+
```
61+
62+
Fish
63+
```fish
64+
curl -L -o browserstack-a11y-scan-spm.sh "https://raw.githubusercontent.com/browserstack/AccessibilityDevTools/refs/heads/main/scripts/fish/spm.sh" && chmod 0775 browserstack-a11y-scan-spm.sh
65+
```
66+
67+
#### Add a Build Phase
68+
Repeat these steps for each target in your project
4969

70+
1. Select a target from the targets left sidebar and go to Build Phases tab
71+
2. Click + to create a new build phase. Name the newly created build phase to a name such as **BrowserStack Accessibility Linter**.
72+
![Build Phase](./resources/build-phase.png "Build Phase")
73+
3. Drag this newly created build phase above **Compile Sources** step
74+
4. Delete any existing code in the newly created build step and add the following code.
75+
5. Add this script:
76+
```
77+
./browserstack-a11y-scan-spm.sh --include **/*.swift --non-strict
78+
```
79+
Xcode will now automatically run the accessibility scan during builds.
80+
81+
### 2. Projects created with Swift package manager
82+
**Register plugin as dependency in your `Package.swift` file**
83+
84+
Edit the `Package.swift` to include following code. Specifically, add these two things:
85+
86+
* Add `AccessibilityDevTools` as a package under dependencies
5087
* Add `a11y-scan` as a plugin under each target that you have in your project
5188

5289
```swift
5390
let package = Package(
54-
name: "MySPMProject",
55-
dependencies: [
56-
.package(url: "https://github.com/browserstack/AccessibilityDevTools.git", from: "1.0.0")
91+
name: "MyProject",
92+
// platforms, products, etc.
93+
dependencies: [
94+
// other dependencies
95+
.package(
96+
url: "https://github.com/browserstack/AccessibilityDevTools.git",
97+
branch: "main"
98+
),
5799
],
58100
targets: [
59-
.executableTarget(
60-
name: "MyApp",
61-
dependencies: [],
62-
plugins: [
63-
.plugin(name: "a11y-scan", package: "AccessibilityDevTools")
64-
]
101+
.executableTarget(
102+
name: "MyApp",
103+
dependencies: [],
104+
plugins: [
105+
.plugin(
106+
name: "a11y-scan",
107+
package: "AccessibilityDevTools"
108+
)
109+
]
65110
)
66111
]
67112
)
68113
```
69-
**Add a Build Phase to run the plugin**
70-
1. Select first item (project root) in the left folder tree and go to Build Phases tab
71-
![Build Phases](./resources/25519c9c-87a9-41af-b97b-23f875faf3b7.png "Build Phases")
72-
2. Click + to create a new build phase. Name the newly created build phase to a name such as **BrowserStack Accessibility Linter**
73-
3. Drag this newly created build phase above **Compile Sources** step
74-
4. Delete any existing code in the newly created build step and add the following code.
75-
5. Add this script:
76-
```bash
77-
/usr/bin/xcrun swift package scan --disable-sandbox --include **/*.swift
78-
```
79114

80-
Xcode will now automatically run the accessibility scan during builds.
115+
#### Clone Script
116+
Run the following command in the <span style="color:red;">root of your repository</span>
117+
118+
Zsh
119+
```zsh
120+
curl -L -o browserstack-a11y-scan-spm.sh "https://raw.githubusercontent.com/browserstack/AccessibilityDevTools/refs/heads/main/scripts/zsh/spm.sh" && chmod 0775 browserstack-a11y-scan-spm.sh
121+
```
81122

82-
### Non-SwiftPM Projects
83-
For all non-SwiftPM projects (e.g. Xcode projects), you can use the **browserstack-cli**
123+
Bash
124+
```bash
125+
curl -L -o browserstack-a11y-scan-spm.sh "https://raw.githubusercontent.com/browserstack/AccessibilityDevTools/refs/heads/main/scripts/bash/spm.sh" && chmod 0775 browserstack-a11y-scan-spm.sh
126+
```
84127

85-
**Install CLI in the project repo**
86-
1. Open terminal and navigate to the project folder.
87-
2. Run the commands provided in the [documentation](https://www.browserstack.com/docs/accessibility-dev-tools/run-checks-cli#install-the-cli)
128+
Fish
129+
```fish
130+
curl -L -o browserstack-a11y-scan-spm.sh "https://raw.githubusercontent.com/browserstack/AccessibilityDevTools/refs/heads/main/scripts/fish/spm.sh" && chmod 0775 browserstack-a11y-scan-spm.sh
131+
```
88132

89-
**Disable Sandboxing**
90-
1. In Xcode project, select first item (project root) in the left folder tree and go to Build Settings tab
91-
2. Search for sandbox > Set user script sandboxing to “NO”
133+
#### Add a Build Phase
134+
Repeat these steps for each target in your project
92135

93-
**Add a Build Phase to run the plugin**
94-
1. Select first item (project root) in the left folder tree and go to Build Phases tab
95-
![Build Phases](./resources/25519c9c-87a9-41af-b97b-23f875faf3b7.png "Build Phases")
136+
1. Select a target from the targets left sidebar and go to Build Phases tab
96137
2. Click + to create a new build phase. Name the newly created build phase to a name such as **BrowserStack Accessibility Linter**
138+
![Build Phase](./resources/build-phase.png "Build Phase")
97139
3. Drag this newly created build phase above **Compile Sources** step
98-
4. Delete any existing code in the newly created build step and add the following code.
140+
4. Delete any existing code in the newly created build step and add the following code.
99141
5. Add this script:
100-
```bash
101-
./browserstack-cli accessibility --include **/*.swift
102142
```
143+
./browserstack-a11y-scan-spm.sh --include **/*.swift --non-strict
144+
```
145+
Xcode will now automatically run the accessibility scan during builds.
103146

104147
---
105148
## Running Accessibility Scans
106-
Press Cmd + B to build the project. If there are no errors from the linter (and any other build steps you have), the build will succeed.
149+
Press Cmd + B to build the project.
150+
* If there are any Accessibility issues, then they will be show up in the Issue Navigator.
151+
![Issue Navigator](./resources/issue-navigator.png "Issue Navigator")
152+
* The errors will also show up in the respective files, on the lines where the issue has occurred. Click on the cross mark to see the full error.
153+
![Issue Details](./resources/issue-details.png "Issue Details")
154+
* If --non-strict flag is passed, the build will succeed even if there are Accessibility issues. If --non-strict flag is not passed, then the build will fail if there are Accessibility issues.
107155

108-
If issues are found:
109-
110-
* Inline red markers show errors in files. Click on the cross mark to see the full error.
111-
![Diagnostics](./resources/bb7fbc3b-6d19-47e9-93c5-8c4b0ae124a6.png "Diagnostics")
112-
* All issues appear in the **Issue Navigator**
113-
![Issue Navigator](./resources/ff9e25c4-0d57-4423-ae0f-fa77b56d99a7.png "Issue Navigator")
156+
---
157+
## Register pre-commit hook
158+
You can run accessibility checks automatically before each commit by running the following command.
159+
```bash
160+
./browserstack-a11y-scan-spm.sh register-pre-commit-hook
161+
```
162+
You can then edit the `.git/hooks/pre-commit` file to customise the registered pre-commit hook.
114163

115164
---
116165
## Support
-217 KB
Binary file not shown.
File renamed without changes.
-418 KB
Binary file not shown.

resources/build-phase.png

444 KB
Loading
-417 KB
Binary file not shown.

resources/issue-details.png

587 KB
Loading

resources/issue-navigator.png

631 KB
Loading

scripts/bash/cli.sh

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#!/usr/bin/env bash -il
2+
3+
GIT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
4+
SCRIPT_PATH=$(realpath --relative-to="$GIT_ROOT" "$0" 2>/dev/null || realpath "$0")
5+
SUBCOMMAND="$1"
6+
EXTRA_ARGS=$@
7+
CACHE_ROOT="${HOME}/.cache/browserstack/devtools/cli/"
8+
BINARY_ZIP_PATH="${CACHE_ROOT}/browserstack-cli.zip"
9+
BINARY_PATH="${CACHE_ROOT}/browserstack-cli"
10+
11+
mkdir -p "$CACHE_ROOT"
12+
13+
get_os() {
14+
local uname_out
15+
uname_out="$(uname -s)"
16+
case "${uname_out}" in
17+
Linux*) os_type=linux;;
18+
Darwin*) os_type=macos;;
19+
*) os_type="UNKNOWN:${uname_out}"
20+
esac
21+
echo "${os_type}"
22+
}
23+
24+
get_arch() {
25+
local arch_out
26+
arch_out="$(uname -m)"
27+
case "${arch_out}" in
28+
x86_64*) arch_type=x64;;
29+
arm64*) arch_type=arm64;;
30+
*) arch_type="UNKNOWN:${arch_out}"
31+
esac
32+
echo "${arch_type}"
33+
}
34+
35+
OS=$(get_os)
36+
ARCH=$(get_arch)
37+
38+
register_git_hook() {
39+
local hook_name="pre-commit"
40+
local hook_path="${GIT_ROOT}/.git/hooks/${hook_name}"
41+
42+
# Check if the hook file already exists
43+
if [ -f "${hook_path}" ]; then
44+
# Append the script execution if not already present
45+
if ! grep -q "${SCRIPT_PATH}" "${hook_path}"; then
46+
echo "" >> "${hook_path}"
47+
echo "# Hook to run accessibility scan before commit" >> "${hook_path}"
48+
echo "${SCRIPT_PATH}" >> "${hook_path}"
49+
echo "if [ \$? -ne 0 ]; then" >> "${hook_path}"
50+
echo " echo \"Accessibility scan failed. Commit aborted.\"" >> "${hook_path}"
51+
echo " exit 1" >> "${hook_path}"
52+
echo "fi" >> "${hook_path}"
53+
fi
54+
else
55+
# Create a new hook file
56+
cat > "${hook_path}" <<EOF
57+
#!/bin/sh
58+
# Hook to run accessibility scan before commit
59+
"${SCRIPT_PATH}"
60+
if [ \$? -ne 0 ]; then
61+
echo "Accessibility scan failed. Commit aborted."
62+
exit 1
63+
fi
64+
EOF
65+
chmod +x "${hook_path}" # Make the hook executable
66+
fi
67+
}
68+
69+
a11y_scan() {
70+
if [[ -z "$EXTRA_ARGS" ]]; then
71+
EXTRA_ARGS="--include **/*.swift"
72+
fi
73+
env -i HOME="$HOME" \
74+
XCODE_VERSION_ACTUAL="$XCODE_VERSION_ACTUAL"\
75+
BROWSERSTACK_USERNAME="$BROWSERSTACK_USERNAME"\
76+
BROWSERSTACK_ACCESS_KEY="$BROWSERSTACK_ACCESS_KEY"\
77+
PATH="$PATH" \
78+
$BINARY_PATH a11y $EXTRA_ARGS
79+
}
80+
81+
script_self_update() {
82+
local remote_url="https://raw.githubusercontent.com/browserstack/AccessibilityDevTools/refs/heads/main/scripts/bash/spm.sh"
83+
84+
updated_script=$(curl -R -z "$SCRIPT_PATH" "$remote_url")
85+
if [[ $updated_script =~ ^#! ]]; then
86+
echo "$updated_script" > "$SCRIPT_PATH"
87+
fi
88+
}
89+
90+
download_binary() {
91+
curl -R -z "$BINARY_ZIP_PATH" -L "http://api.browserstack.com/sdk/v1/download_cli?os=${OS}&os_arch=${ARCH}" -o "$BINARY_ZIP_PATH"
92+
bsdtar -xvf "$BINARY_ZIP_PATH" -O > "$BINARY_PATH" && chmod 0775 "$BINARY_PATH"
93+
}
94+
95+
script_self_update
96+
if [[ $SUBCOMMAND == "register-pre-commit-hook" ]]; then
97+
register_git_hook
98+
exit 0
99+
fi
100+
101+
download_binary
102+
a11y_scan

scripts/bash/spm.sh

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#!/usr/bin/env bash -il
2+
3+
[ -f "${PWD}/Package.swift" ]
4+
PACKAGE_EXISTS="$?"
5+
GIT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
6+
SCRIPT_PATH=$(realpath --relative-to="$GIT_ROOT" "$0" 2>/dev/null || realpath "$0")
7+
SUBCOMMAND="$1"
8+
EXTRA_ARGS=$@
9+
10+
register_git_hook() {
11+
local hook_name="pre-commit"
12+
local hook_path="${GIT_ROOT}/.git/hooks/${hook_name}"
13+
14+
# Check if the hook file already exists
15+
if [ -f "${hook_path}" ]; then
16+
# Append the script execution if not already present
17+
if ! grep -q "${SCRIPT_PATH}" "${hook_path}"; then
18+
echo "" >> "${hook_path}"
19+
echo "# Hook to run accessibility scan before commit" >> "${hook_path}"
20+
echo "${SCRIPT_PATH}" >> "${hook_path}"
21+
echo "if [ \$? -ne 0 ]; then" >> "${hook_path}"
22+
echo " echo \"Accessibility scan failed. Commit aborted.\"" >> "${hook_path}"
23+
echo " exit 1" >> "${hook_path}"
24+
echo "fi" >> "${hook_path}"
25+
fi
26+
else
27+
# Create a new hook file
28+
cat > "${hook_path}" <<EOF
29+
#!/bin/sh
30+
# Hook to run accessibility scan before commit
31+
"${SCRIPT_PATH}"
32+
if [ \$? -ne 0 ]; then
33+
echo "Accessibility scan failed. Commit aborted."
34+
exit 1
35+
fi
36+
EOF
37+
chmod +x "${hook_path}" # Make the hook executable
38+
fi
39+
}
40+
41+
a11y_scan() {
42+
# Ensure Package.swift is removed on exit (acts like a finally block)
43+
cleanup() {
44+
if [ $PACKAGE_EXISTS -eq 0 ]; then
45+
return
46+
fi
47+
rm -f -- "${PWD}/Package.swift" "${PWD}/Package.resolved"
48+
}
49+
trap cleanup EXIT
50+
51+
setup() {
52+
if [ $PACKAGE_EXISTS -eq 0 ]; then
53+
return
54+
fi
55+
56+
cat > Package.swift <<EOF
57+
// swift-tools-version: 5.9
58+
import PackageDescription
59+
60+
let package = Package(
61+
name: "Dummy",
62+
dependencies: [
63+
.package(url: "https://github.com/browserstack/AccessibilityDevTools.git", branch: "main")
64+
],
65+
targets: []
66+
)
67+
EOF
68+
}
69+
70+
setup
71+
if [[ -z "$EXTRA_ARGS" ]]; then
72+
EXTRA_ARGS="--include **/*.swift"
73+
fi
74+
env -i HOME="$HOME" \
75+
XCODE_VERSION_ACTUAL="$XCODE_VERSION_ACTUAL"\
76+
BROWSERSTACK_USERNAME="$BROWSERSTACK_USERNAME"\
77+
BROWSERSTACK_ACCESS_KEY="$BROWSERSTACK_ACCESS_KEY"\
78+
PATH="$PATH" \
79+
swift package plugin \
80+
--allow-writing-to-directory ~/.cache\
81+
--allow-writing-to-package-directory\
82+
--allow-network-connections 'all(ports: [])'\
83+
scan $EXTRA_ARGS
84+
}
85+
86+
script_self_update() {
87+
local remote_url="https://raw.githubusercontent.com/browserstack/AccessibilityDevTools/refs/heads/main/scripts/bash/spm.sh"
88+
89+
updated_script=$(curl -R -z "$SCRIPT_PATH" "$remote_url")
90+
if [[ $updated_script =~ ^#! ]]; then
91+
echo "$updated_script" > "$SCRIPT_PATH"
92+
fi
93+
}
94+
95+
script_self_update
96+
if [[ $SUBCOMMAND == "register-pre-commit-hook" ]]; then
97+
register_git_hook
98+
exit 0
99+
fi
100+
101+
a11y_scan

0 commit comments

Comments
 (0)