Skip to content

Commit

Permalink
hide voice search icon on mobile except for select browsers (#1662)
Browse files Browse the repository at this point in the history
This PR updates the SearchBar to only display the voice search
icon on mobile for select browsers that are known to have support
for it. Previously, the voice search icon could appear even when
SpeechRecognition was not supported, for example on Chrome for iOS.

Since we are now using the Bowser package for user agent sniffing,
we no longer need our userAgent acceptance test suite.
After this PR I can remove them from the gh-action migration feature branch.

J=SLAP-1704
TEST=manual

go on browserstack/personal phone
use mkcert and the http-server with the `-S` flag for https, so that `navigator.mediaDevices` will exist
see that voice search appears for safari ios, chrome android
see that voice search does NOT appear for chrome ios, firefox android
for samsung internet for android add a window.alert to show that the bowser's useragent sniffing works as expected, since this browser does not have a "visit anyway" for https sites with self signed certificates
voice search icon still shows up on edge, chrome, safari desktop browsers, and does not show up on firefox desktop
  • Loading branch information
oshi97 committed Feb 1, 2022
1 parent 9186f53 commit 92b5fdf
Show file tree
Hide file tree
Showing 11 changed files with 79 additions and 173 deletions.
25 changes: 0 additions & 25 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,15 +125,6 @@ jobs:
- attach_workspace:
at: ~/answers
- run: ./.circleci/run_browserstack_acceptance.sh
useragent_acceptance_test:
docker:
- image: circleci/node:14.5-browsers
working_directory: ~/answers
steps:
- setup-workspace
- attach_workspace:
at: ~/answers
- run: ./.circleci/run_useragent_acceptance.sh
# verify all translations are present
translation_test:
docker:
Expand Down Expand Up @@ -236,17 +227,13 @@ workflows:
- browserstack_acceptance_test:
requires:
- build
- useragent_acceptance_test:
requires:
- build
- translation_test:
requires:
- build
- deploy_branch:
requires:
- unit_test
- browserstack_acceptance_test
- useragent_acceptance_test
- headless_acceptance_test
build_and_deploy_i18n:
jobs:
Expand All @@ -268,9 +255,6 @@ workflows:
- browserstack_acceptance_test:
requires:
- build_i18n
- useragent_acceptance_test:
requires:
- build_i18n
- translation_test:
requires:
- build_i18n
Expand All @@ -282,7 +266,6 @@ workflows:
requires:
- unit_test
- browserstack_acceptance_test
- useragent_acceptance_test
- headless_acceptance_test
- translation_test
- deploy_canary:
Expand All @@ -293,7 +276,6 @@ workflows:
- unit_test
- headless_acceptance_test
- browserstack_acceptance_test
- useragent_acceptance_test
build_and_deploy_hold:
jobs:
- build_i18n:
Expand All @@ -320,12 +302,6 @@ workflows:
only: /^v.*/
requires:
- build_i18n
- useragent_acceptance_test:
filters:
tags:
only: /^v.*/
requires:
- build_i18n
- translation_test:
filters:
tags:
Expand All @@ -340,7 +316,6 @@ workflows:
requires:
- unit_test
- browserstack_acceptance_test
- useragent_acceptance_test
- headless_acceptance_test
- translation_test
- deploy_version:
Expand Down
8 changes: 0 additions & 8 deletions .circleci/run_useragent_acceptance.sh

This file was deleted.

4 changes: 2 additions & 2 deletions .size-limit.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
module.exports = [
{
path: 'dist/answers.min.js',
limit: '170 KB'
limit: '180 KB'
},
{
path: 'dist/answers-modern.min.js',
limit: '142kb'
limit: '150kb'
},
{
path: 'dist/answerstemplates.compiled.min.js',
Expand Down
48 changes: 48 additions & 0 deletions THIRD-PARTY-NOTICES
Original file line number Diff line number Diff line change
Expand Up @@ -1268,6 +1268,54 @@ SOFTWARE.

-----------

The following NPM package may be included in this product:

- bowser@2.11.0

This package contains the following license and notice below:

Copyright 2015, Dustin Diaz (the "Original Author")
All rights reserved.

MIT License

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

Distributions of all or part of the Software intended to be used
by the recipients as they would use the unmodified Software,
containing modifications that substantially alter, remove, or
disable functionality of the Software, outside of the documented
configuration mechanisms provided by the Software, shall be
modified such that the Original Author's bug reporting email
addresses and urls are either replaced with the contact information
of the parties responsible for the changes, or removed entirely.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.


Except where noted, this license applies to any and all software
programs and associated documentation files created by the
Original Author, when distributed with the Software.

-----------

The following NPM package may be included in this product:

- brace-expansion@1.1.11
Expand Down
3 changes: 1 addition & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"@yext/answers-core": "^1.5.0-beta.0",
"@yext/answers-storage": "^1.1.0",
"@yext/rtf-converter": "^1.5.0",
"bowser": "^2.11.0",
"cross-fetch": "^3.1.4",
"css-vars-ponyfill": "^2.4.3",
"gulp-sourcemaps": "^2.6.5",
Expand Down
18 changes: 17 additions & 1 deletion src/core/speechrecognition/support.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import Bowser from 'bowser';

/**
* Whether the SpeechRecognition API is supported by the current browser.
*
Expand All @@ -9,5 +11,19 @@
* @returns {boolean}
*/
export function speechRecognitionIsSupported () {
return !!(window.webkitSpeechRecognition && navigator.mediaDevices);
if (!(window.webkitSpeechRecognition && navigator.mediaDevices)) {
return false;
}

const browserData = Bowser.parse(navigator.userAgent);
if (browserData.platform.type === 'desktop') {
return true;
}

const os = browserData.os.name;
const browser = browserData.browser.name;

return (browser === 'Safari' && os === 'iOS') ||
(browser === 'Chrome' && os === 'Android') ||
(browser === 'Samsung Internet for Android' && os === 'Android');
}
42 changes: 7 additions & 35 deletions src/core/utils/useragent.js
Original file line number Diff line number Diff line change
@@ -1,51 +1,23 @@
import Bowser from 'bowser';

/**
* Returns whether the current browser is Microsoft Edge.
* Tries to use User-Agent clients hints, and defaults to
* using the User-Agent string if clients hints are not supported.
*
* @returns {boolean}
*/
export function isMicrosoftEdge () {
const brands = navigator.userAgentData?.brands;
if (brands && brands.length > 0) {
return !!brands.find(b => b.brand === 'Microsoft Edge');
} else if (navigator.userAgent) {
return navigator.userAgent.includes('Edg');
}
const browserData = Bowser.parse(navigator.userAgent);

return browserData.browser.name === 'Microsoft Edge';
}

/**
* Returns whether the current browser is Safari.
* Currently, Safari does not support User-Agent clients hints (userAgentData).
* Chrome likes to pretend that it's Safari.
* Edge also likes to pretend that it's Safari.
*
* @returns {boolean}
*/
export function isSafari () {
if (isChrome()) {
return false;
}
if (isMicrosoftEdge()) {
return false;
}
return navigator.userAgent.includes('Safari');
}
const browserData = Bowser.parse(navigator.userAgent);

/**
* Returns whether the current browser is Chrome.
* Edge likes to pretend that it is Chrome.
*
* @returns {boolean}
*/
export function isChrome () {
if (isMicrosoftEdge()) {
return false;
}
const brands = navigator.userAgentData?.brands;
if (brands && brands.length > 0) {
return !!brands.find(b => b.brand === 'Google Chrome');
} else if (navigator.userAgent) {
return navigator.userAgent.includes('Chrome');
}
return browserData.browser.name === 'Safari';
}
33 changes: 0 additions & 33 deletions tests/acceptance/useragent/useragentsuite.js

This file was deleted.

66 changes: 0 additions & 66 deletions tests/core/utils/useragent.js

This file was deleted.

4 changes: 3 additions & 1 deletion tests/ui/components/search/searchcomponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,9 @@ describe('SearchBar component', () => {
getUserMedia: () => Promise.resolve({
getTracks: () => ([{ stop: jest.fn() }])
})
}
},
// taken from Safari on MacOS
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15'
}));
});

Expand Down

0 comments on commit 92b5fdf

Please sign in to comment.