diff --git a/.github/workflows/cross-browser-testing-android.yml b/.github/workflows/cross-browser-testing-android.yml new file mode 100644 index 000000000..d85d41536 --- /dev/null +++ b/.github/workflows/cross-browser-testing-android.yml @@ -0,0 +1,39 @@ +name: 'BrowserStack Android Mobile Test' +on: [push, workflow_dispatch] + +jobs: + browserstack-android-test: + name: 'BrowserStack Android Mobile Test' + runs-on: ubuntu-latest + steps: + - name: 'BrowserStack Env Setup' + uses: browserstack/github-actions/setup-env@master + with: + username: ${{ secrets.BROWSERSTACK_USERNAME }} + access-key: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} + + - name: 'BrowserStack Local Tunnel Setup' + uses: browserstack/github-actions/setup-local@master + with: + local-testing: start + local-identifier: random + + - name: 'Checkout the repository' + uses: actions/checkout@v3 + + - name: 'Run NPM CI' + run: npm ci + + - name: Run Build IIFE + run: npm run build:iife + + - name: 'Run NPM build test bundle' + run: npm run build:test-bundle + + - name: 'Run Browserstack Android Mobile Tests' + run: npm run test:browserstack-android + + - name: 'BrowserStackLocal Stop' + uses: browserstack/github-actions/setup-local@master + with: + local-testing: stop diff --git a/.github/workflows/cross-browser-testing-iOS.yml b/.github/workflows/cross-browser-testing-iOS.yml new file mode 100644 index 000000000..34db2d594 --- /dev/null +++ b/.github/workflows/cross-browser-testing-iOS.yml @@ -0,0 +1,39 @@ +name: 'BrowserStack iOS Mobile Test' +on: [push, workflow_dispatch] + +jobs: + browserstack-iOS-test: + name: 'BrowserStack iOS Mobile Test' + runs-on: ubuntu-latest + steps: + - name: 'BrowserStack Env Setup' + uses: browserstack/github-actions/setup-env@master + with: + username: ${{ secrets.BROWSERSTACK_USERNAME }} + access-key: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} + + - name: 'BrowserStack Local Tunnel Setup' + uses: browserstack/github-actions/setup-local@master + with: + local-testing: start + local-identifier: random + + - name: 'Checkout the repository' + uses: actions/checkout@v3 + + - name: 'Run NPM CI' + run: npm ci + + - name: Run Build IIFE + run: npm run build:iife + + - name: 'Run NPM build test bundle' + run: npm run build:test-bundle + + - name: 'Run Browserstack iOS Mobile Tests' + run: npm run test:browserstack-iOS + + - name: 'BrowserStackLocal Stop' + uses: browserstack/github-actions/setup-local@master + with: + local-testing: stop diff --git a/.github/workflows/cross-browser-testing.yml b/.github/workflows/cross-browser-testing.yml index 1573eba7c..a7e2f5133 100644 --- a/.github/workflows/cross-browser-testing.yml +++ b/.github/workflows/cross-browser-testing.yml @@ -2,7 +2,7 @@ # https://github.com/browserstack/github-actions?tab=readme-ov-file#sample-workflow-with-usage-of-both-actions name: 'BrowserStack Test' -on: [push, pull_request, workflow_dispatch] +on: [push, workflow_dispatch] jobs: browserstack-test: diff --git a/package.json b/package.json index e082f135a..606f79c54 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,10 @@ "test": "npm run build && npm run build:test-bundle && cross-env DEBUG=false karma start test/karma.config.js", "test:browserstack": "karma start test/cross-browser-testing/browserstack.karma.config.js", "test:browserstack:debug": "cross-env DEBUG=true karma start test/cross-browser-testing/browserstack.karma.config.js", + "test:browserstack-android": "karma start test/cross-browser-testing/browserstack.karma.android.config.js", + "test:browserstack-android:debug": "cross-env DEBUG=true karma start test/cross-browser-testing/browserstack.karma.android.config.js", + "test:browserstack-iOS": "karma start test/cross-browser-testing/browserstack.karma.iOS.config.js", + "test:browserstack-iOS:debug": "cross-env DEBUG=true karma start test/cross-browser-testing/browserstack.karma.iOS.config.js", "test:browserstack-beta": "karma start test/cross-browser-testing/browserstack.karma.beta.config.js", "test:browserstack-beta:debug": "cross-env DEBUG=true karma start test/cross-browser-testing/browserstack.karma.beta.config.js", "test:debug": "cross-env DEBUG=true karma start test/karma.config.js", diff --git a/test/cross-browser-testing/browserstack.karma.android.config.js b/test/cross-browser-testing/browserstack.karma.android.config.js new file mode 100644 index 000000000..792ace099 --- /dev/null +++ b/test/cross-browser-testing/browserstack.karma.android.config.js @@ -0,0 +1,151 @@ +const { DEBUG } = process.env; + +const files = [ + '../lib/geomock.js', + '../../dist/mparticle.js', + '../test-bundle.js', +]; + +let captureConsole = false; +let browserConsoleLogOptions = {}; + +if (DEBUG === 'true') { + browserConsoleLogOptions = { + level: 'log', + format: '%b %T: %m', + terminal: true, + }; + captureConsole = true; +} else { + browserConsoleLogOptions = { + terminal: false, + }; +} + +const customLaunchers = { + // Android 16 - all browsers + bs_android_16_chrome: { + base: 'BrowserStack', + device: 'Google Pixel 10 Pro', + os: 'android', + os_version: '16.0', + real_mobile: true, + browser: 'chrome' + }, + bs_android_16_firefox: { + base: 'BrowserStack', + device: 'Google Pixel 10', + os: 'android', + os_version: '16.0', + real_mobile: true, + browser: 'firefox' + }, + bs_android_16_opera: { + base: 'BrowserStack', + device: 'Google Pixel 10 Pro', + os: 'android', + os_version: '16.0', + real_mobile: true, + browser: 'opera' + }, + bs_android_16_samsung: { + base: 'BrowserStack', + device: 'Google Pixel 10 Pro XL', + os: 'android', + os_version: '16.0', + real_mobile: true, + browser: 'samsung' + }, + + // Android 15 - all browsers + bs_android_15_chrome: { + base: 'BrowserStack', + device: 'Samsung Galaxy S25', + os: 'android', + os_version: '15.0', + real_mobile: true, + browser: 'chrome' + }, + bs_android_15_firefox: { + base: 'BrowserStack', + device: 'Samsung Galaxy Tab S10 Plus', + os: 'android', + os_version: '15.0', + real_mobile: true, + browser: 'firefox' + }, + bs_android_15_opera: { + base: 'BrowserStack', + device: 'Google Pixel 9 Pro', + os: 'android', + os_version: '15.0', + real_mobile: true, + browser: 'opera' + }, + bs_android_15_samsung: { + base: 'BrowserStack', + device: 'Samsung Galaxy S25 Ultra', + os: 'android', + os_version: '15.0', + real_mobile: true, + browser: 'samsung' + }, + + // Android 14 - chrome + bs_android_14_chrome: { + base: 'BrowserStack', + device: 'Samsung Galaxy S24', + os: 'android', + os_version: '14.0', + real_mobile: true, + browser: 'chrome' + }, + + // Android 13 - chrome + bs_android_13_chrome: { + base: 'BrowserStack', + device: 'Samsung Galaxy S23 Ultra', + os: 'android', + os_version: '13.0', + real_mobile: true, + browser: 'chrome' + }, +}; + +module.exports = function(config) { + config.set({ + browserStack: { + username: process.env.BS_USERNAME, + accessKey: process.env.BS_ACCESS_KEY, + local: true, + idleTimeout: 300, + }, + autoWatch: false, + customLaunchers, + browsers: Object.keys(customLaunchers), + frameworks: ['mocha', 'should'], + files, + reporters: ['progress', 'junit'], + colors: true, + singleRun: true, + debug: true, + logLevel: config.LOG_INFO, + browserConsoleLogOptions, + client: { + captureConsole, + mocha: { + timeout: 10000 + } + }, + junitReporter: { + outputDir: 'reports/', + outputFile: 'test-karma-mobile.xml', + }, + captureTimeout: 240000, + browserNoActivityTimeout: 240000, + browserDisconnectTimeout: 120000, + browserDisconnectTolerance: 5, + concurrency: 5, + retryLimit: 2, + }); +}; diff --git a/test/cross-browser-testing/browserstack.karma.config.js b/test/cross-browser-testing/browserstack.karma.config.js index 556f09986..657b19f7d 100644 --- a/test/cross-browser-testing/browserstack.karma.config.js +++ b/test/cross-browser-testing/browserstack.karma.config.js @@ -70,7 +70,8 @@ module.exports = function(config) { config.set({ browserStack: { username: process.env.BS_USERNAME, - accessKey: process.env.BS_ACCESS_KEY + accessKey: process.env.BS_ACCESS_KEY, + idleTimeout: 300, }, autoWatch: false, customLaunchers, @@ -90,11 +91,11 @@ module.exports = function(config) { outputDir: 'reports/', outputFile: 'test-karma.xml', }, - // These settings are added because the connection to Browserstack - // can sometimes be unstable, requiring re-connections, or a longer than - // 2000 ms (default) timeout - browserDisconnectTimeout: 50000, - browserDisconnectTolerance: 5, - concurrency: 5, + captureTimeout: 180000, + browserNoActivityTimeout: 180000, + browserDisconnectTimeout: 120000, + browserDisconnectTolerance: 1, + concurrency: 2, + retryLimit: 2, }); }; diff --git a/test/cross-browser-testing/browserstack.karma.iOS.config.js b/test/cross-browser-testing/browserstack.karma.iOS.config.js new file mode 100644 index 000000000..c98c08c94 --- /dev/null +++ b/test/cross-browser-testing/browserstack.karma.iOS.config.js @@ -0,0 +1,131 @@ +const { DEBUG } = process.env; + +const files = [ + '../lib/geomock.js', + '../../dist/mparticle.js', + '../test-bundle.js', +]; + +let captureConsole = false; +let browserConsoleLogOptions = {}; + +if (DEBUG === 'true') { + browserConsoleLogOptions = { + level: 'log', + format: '%b %T: %m', + terminal: true, + }; + captureConsole = true; +} else { + browserConsoleLogOptions = { + terminal: false, + }; +} + +const customLaunchers = { + // iOS 26 - chrome, firefox, safari + bs_ios_26_safari: { + base: 'BrowserStack', + device: 'iPhone 17 Pro', + os: 'ios', + os_version: '26', + real_mobile: true, + browser: 'safari' + }, + bs_ios_26_chrome: { + base: 'BrowserStack', + device: 'iPad Air 5', + os: 'ios', + os_version: '26', + real_mobile: true, + browser: 'chrome' + }, + bs_ios_26_firefox: { + base: 'BrowserStack', + device: 'iPhone Air', + os: 'ios', + os_version: '26', + real_mobile: true, + browser: 'firefox' + }, + + // iOS 18 - chrome, firefox, safari + bs_ios_18_safari: { + base: 'BrowserStack', + device: 'iPhone 16e', + os: 'ios', + os_version: '18', + real_mobile: true, + browser: 'safari' + }, + bs_ios_18_chrome: { + base: 'BrowserStack', + device: 'iPad Pro 11 2021', + os: 'ios', + os_version: '18', + real_mobile: true, + browser: 'chrome' + }, + bs_ios_18_firefox: { + base: 'BrowserStack', + device: 'iPhone 14', + os: 'ios', + os_version: '18', + real_mobile: true, + browser: 'firefox' + }, + + // iOS 17 - chrome + bs_ios_17_chrome: { + base: 'BrowserStack', + device: 'iPhone 12', + os: 'ios', + os_version: '17', + real_mobile: true, + browser: 'chrome' + }, + + // iOS 16 - safari + bs_ios_16_safari: { + base: 'BrowserStack', + device: 'iPad 10th', + os: 'ios', + os_version: '16', + real_mobile: true, + browser: 'safari' + }, +}; + +module.exports = function(config) { + config.set({ + browserStack: { + username: process.env.BS_USERNAME, + accessKey: process.env.BS_ACCESS_KEY, + local: true, + }, + autoWatch: false, + customLaunchers, + browsers: Object.keys(customLaunchers), + frameworks: ['mocha', 'should'], + files, + reporters: ['progress', 'junit'], + colors: true, + singleRun: true, + debug: true, + logLevel: config.LOG_INFO, + browserConsoleLogOptions, + client: { + captureConsole, + mocha: { + timeout: 10000 + } + }, + junitReporter: { + outputDir: 'reports/', + outputFile: 'test-karma-mobile.xml', + }, + browserDisconnectTimeout: 50000, + browserDisconnectTolerance: 5, + concurrency: 5, + }); +};