Skip to content

Commit

Permalink
Show Chrome extension instructions in the homepage if visited from Ch…
Browse files Browse the repository at this point in the history
…romium browsers (#5251)

Now that we have [a Chrome
extension](https://github.com/firefox-devtools/firefox-profiler-for-chrome),
let's show an instruction to install it in the profiler home page if
it's visited from Chromium based browsers.

I was also thinking about showing the recording instructions if we
detect that the chrome extension is already installed, but I don't think
we have to have that for the first iteration as this is a clear
improvement to the previous version. I would prefer to implement that as
a follow-up, as it will require changes in the extension code and we
will have to publish that new extension version.
  • Loading branch information
canova authored Dec 9, 2024
2 parents 6a683fa + 1863710 commit 6306555
Show file tree
Hide file tree
Showing 4 changed files with 356 additions and 0 deletions.
8 changes: 8 additions & 0 deletions locales/en-US/app.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,14 @@ Home--load-files-from-other-tools2 =
Format</traceevent>. <write>Learn how to write your
own importer</write>.
Home--install-chrome-extension = Install the Chrome extension
Home--chrome-extension-instructions = Use the <a>{ -profiler-brand-name } extension for Chrome</a>
to capture performance profiles in Chrome and analyze them in the
{ -profiler-brand-name }. Install the extension from the Chrome Web Store.
Home--chrome-extension-recording-instructions = Once installed, use the extension’s
toolbar icon or the shortcuts to start and stop profiling. You can also
export profiles and load them here for detailed analysis.
## IdleSearchField
## The component that is used for all the search inputs in the application.

Expand Down
74 changes: 74 additions & 0 deletions src/components/app/Home.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ type PopupInstallPhase =
| 'popup-enabled'
| 'suggest-enable-popup'
// Other browsers:
| 'suggest-chrome-extension'
| 'other-browser';

class HomeImpl extends React.PureComponent<HomeProps, HomeState> {
Expand All @@ -249,6 +250,10 @@ class HomeImpl extends React.PureComponent<HomeProps, HomeState> {
this.setState({ popupInstallPhase: 'webchannel-unavailable' });
}
);
} else if (_isChromium()) {
popupInstallPhase = 'suggest-chrome-extension';
// TODO: Check if the extension is installed and show the recording
// instructions. But we need to check if extension is there to do that.
}

this.state = {
Expand All @@ -266,6 +271,8 @@ class HomeImpl extends React.PureComponent<HomeProps, HomeState> {
return this._renderEnablePopupInstructions(false);
case 'popup-enabled':
return this._renderRecordInstructions(FirefoxPopupScreenshot);
case 'suggest-chrome-extension':
return this._renderChromeInstructions();
case 'other-browser':
return this._renderOtherBrowserInstructions();
default:
Expand Down Expand Up @@ -376,6 +383,69 @@ class HomeImpl extends React.PureComponent<HomeProps, HomeState> {
);
}

_renderChromeInstructions() {
const chromeExtensionUrl =
'https://chromewebstore.google.com/detail/firefox-profiler/ljmahpnflmbkgaipnfbpgjipcnahlghn';
return (
<InstructionTransition key={0}>
<div
className="homeInstructions"
data-testid="home-enable-popup-instructions"
>
{/* Grid container: homeInstructions */}
{/* Left column: img */}
<img
className="homeSectionScreenshot"
src={PerfScreenshot}
alt="screenshot of profiler.firefox.com"
/>
{/* Right column: instructions */}
<div>
<a
className="homeSectionButton"
href={chromeExtensionUrl}
target="_blank"
rel="noreferrer"
>
<span className="homeSectionPlus">+</span>
<Localized id="Home--install-chrome-extension">
Install the Chrome extension
</Localized>
</a>
<DocsButton />
<Localized
id="Home--chrome-extension-instructions"
elems={{
a: (
<a
href={chromeExtensionUrl}
target="_blank"
rel="noreferrer"
/>
),
}}
>
<p>
Use the <a>Firefox Profiler extension for Chrome</a> to capture
performance profiles in Chrome and analyze them in the Firefox
Profiler. Install the extension from the Chrome Web Store.
</p>
</Localized>
<Localized id="Home--chrome-extension-recording-instructions">
<p>
Once installed, use the extension’s toolbar icon or the
shortcuts to start and stop profiling. You can also export
profiles and load them here for detailed analysis.
</p>
</Localized>
{this._renderShortcuts()}
</div>
{/* end of grid container */}
</div>
</InstructionTransition>
);
}

_renderRecordInstructions(screenshotSrc: string) {
return (
<InstructionTransition key={1}>
Expand Down Expand Up @@ -627,6 +697,10 @@ function _isFirefox(): boolean {
return Boolean(navigator.userAgent.match(/Firefox\/\d+\.\d+/));
}

function _isChromium(): boolean {
return Boolean(navigator.userAgent.match(/Chrome\/\d+\.\d+/));
}

export const Home = explicitConnect<
OwnHomeProps,
StateHomeProps,
Expand Down
7 changes: 7 additions & 0 deletions src/test/components/Home.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ const FIREFOX =
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:55.0) Gecko/20100101 Firefox/55.0';
const SAFARI =
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8';
const CHROME =
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/603.3.8 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36';
let userAgent;

// Flow doesn't understand Object.defineProperty. Use the "any" type to use it anyway.
Expand All @@ -48,6 +50,11 @@ describe('app/Home', function () {
expect(container.firstChild).toMatchSnapshot();
});

it('renders the Chrome extension instructions for Chromium based browsers', () => {
const { container } = setup(CHROME);
expect(container.firstChild).toMatchSnapshot();
});

it('renders the information screen for other browsers', () => {
const { container } = setup(SAFARI);
expect(container.firstChild).toMatchSnapshot();
Expand Down
Loading

0 comments on commit 6306555

Please sign in to comment.