├── .commitlintrc
├── .editorconfig
├── .eslintrc
├── .firebaserc
├── .github
├── dependabot.yml
└── workflows
│ ├── check-linked-issues.yml
│ ├── ci.yml
│ ├── notify-release.yml
│ └── release.yml
├── .gitignore
├── .husky
├── commit-msg
└── pre-commit
├── .nvmrc
├── .prettierrc
├── LICENSE
├── README.md
├── babel.config.cjs
├── example
├── .env.sample
├── .gitignore
├── README.md
├── package-lock.json
├── package.json
├── playwright.config.ts
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── App.css
│ ├── App.test.tsx
│ ├── App.tsx
│ ├── hooks
│ │ └── useAuth.tsx
│ ├── index.css
│ ├── index.tsx
│ ├── logo.svg
│ ├── provider
│ │ └── AuthProvider.tsx
│ ├── react-app-env.d.ts
│ ├── reportWebVitals.ts
│ └── setupTests.ts
├── test-examples
│ ├── auth.setup.ts
│ └── example.spec.ts
└── tsconfig.json
├── index.ts
├── jest.config.ts
├── package-lock.json
├── package.json
├── plugin
├── Authentication.ts
└── auth.setup.ts
├── tests
├── Authentication.test.ts
└── authsetup.test.ts
└── tsconfig.json
/.commitlintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "@commitlint/config-conventional"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | [*]
2 | end_of_line = lf
3 | insert_final_newline = true
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "node": true,
4 | "commonjs": true
5 | },
6 | "root": true,
7 | "parser": "@typescript-eslint/parser",
8 | "plugins": [
9 | "@typescript-eslint"
10 | ],
11 | "extends": [
12 | "eslint:recommended",
13 | "plugin:@typescript-eslint/eslint-recommended",
14 | "plugin:@typescript-eslint/recommended"
15 | ],
16 | "ignorePatterns": [
17 | "/dist/**/*"
18 | ]
19 | }
20 |
--------------------------------------------------------------------------------
/.firebaserc:
--------------------------------------------------------------------------------
1 | {
2 | "projects": {
3 | "default": "playwright-firebase-plugin"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: npm
4 | directory: /
5 | schedule:
6 | interval: weekly
7 | - package-ecosystem: github-actions
8 | directory: /
9 | schedule:
10 | interval: weekly
11 |
--------------------------------------------------------------------------------
/.github/workflows/check-linked-issues.yml:
--------------------------------------------------------------------------------
1 | name: Check linked issues
2 | 'on':
3 | pull_request_target:
4 | types:
5 | - opened
6 | - edited
7 | - reopened
8 | - synchronize
9 | jobs:
10 | check_pull_requests:
11 | runs-on: ubuntu-latest
12 | name: Check linked issues
13 | permissions:
14 | issues: read
15 | pull-requests: write
16 | steps:
17 | - uses: nearform-actions/github-action-check-linked-issues@v1
18 | id: check-linked-issues
19 | with:
20 | exclude-branches: release/**, dependabot/**
21 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: Continuous Integration
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | pull_request:
8 |
9 | jobs:
10 | test:
11 | name: Lint and test
12 | runs-on: ubuntu-latest
13 | env:
14 | REACT_APP_UID: ${{ secrets.REACT_APP_UID }}
15 | REACT_APP_FIREBASE_CONFIG: ${{ secrets.REACT_APP_FIREBASE_CONFIG }}
16 | SERVICE_ACCOUNT: ${{ secrets.SERVICE_ACCOUNT }}
17 | steps:
18 | - uses: actions/checkout@v4
19 | - uses: actions/setup-node@v4
20 | with:
21 | node-version-file: '.nvmrc'
22 | - run: |
23 | npm ci
24 | npm run pw
25 | npm run lint
26 | npm run test
27 |
28 | automerge:
29 | name: Merge dependabot's PRs
30 | needs: test
31 | runs-on: ubuntu-latest
32 | permissions:
33 | pull-requests: write
34 | contents: write
35 | steps:
36 | - uses: fastify/github-action-merge-dependabot@v3
37 |
--------------------------------------------------------------------------------
/.github/workflows/notify-release.yml:
--------------------------------------------------------------------------------
1 | name: Notify release
2 | 'on':
3 | workflow_dispatch:
4 | schedule:
5 | - cron: 30 8 * * *
6 | release:
7 | types:
8 | - published
9 | issues:
10 | types:
11 | - closed
12 | jobs:
13 | setup:
14 | runs-on: ubuntu-latest
15 | permissions:
16 | issues: write
17 | contents: read
18 | steps:
19 | - uses: nearform-actions/github-action-notify-release@v1
20 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: release
2 | on:
3 | workflow_dispatch:
4 | inputs:
5 | semver:
6 | description: The semver to use
7 | required: true
8 | default: patch
9 | type: choice
10 | options:
11 | - patch
12 | - minor
13 | - major
14 | pull_request:
15 | types: [closed]
16 |
17 | jobs:
18 | release:
19 | permissions:
20 | contents: write
21 | issues: write
22 | pull-requests: write
23 | id-token: write
24 | runs-on: ubuntu-latest
25 | steps:
26 | - uses: nearform-actions/optic-release-automation-action@v4
27 | with:
28 | semver: ${{ github.event.inputs.semver }}
29 | commit-message: 'chore: release {version}'
30 | npm-token: >-
31 | ${{ secrets[format('NPM_TOKEN_{0}', github.actor)] ||
32 | secrets.NPM_TOKEN }}
33 | optic-token: >-
34 | ${{ secrets[format('OPTIC_TOKEN_{0}', github.actor)] ||
35 | secrets.OPTIC_TOKEN }}
36 | build-command: npm ci
37 | provenance: true
38 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .eslintcache
3 |
4 | # JetBrains IDEs
5 | .idea
6 | # Visual Studio Code
7 | .vscode
8 |
9 | # OS X
10 | .DS_Store
11 | /test-results/
12 | /playwright-report/
13 | /playwright/.cache/
14 | .auth
15 | serviceAccount.json
16 | .env
17 | dist
18 |
19 |
20 | cjs
--------------------------------------------------------------------------------
/.husky/commit-msg:
--------------------------------------------------------------------------------
1 | npx --no -- commitlint --edit $1
2 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | npx lint-staged
2 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | lts/*
2 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "semi": false,
3 | "singleQuote": true,
4 | "arrowParens": "avoid",
5 | "trailingComma": "none"
6 | }
7 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 |
3 | Version 2.0, January 2004
4 |
5 | http://www.apache.org/licenses/ TERMS
6 | AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 |
11 |
12 |
13 | "License" shall mean the terms and conditions for use, reproduction, and
14 | distribution as defined by Sections 1 through 9 of this document.
15 |
16 |
17 |
18 |
19 | "Licensor" shall mean the copyright owner or entity authorized by the copyright
20 | owner that is granting the License.
21 |
22 |
23 |
24 | "Legal Entity" shall mean the
25 | union of the acting entity and all other entities that control, are controlled
26 | by, or are under common control with that entity. For the purposes of this
27 | definition, "control" means (i) the power, direct or indirect, to cause the
28 | direction or management of such entity, whether by contract or otherwise, or (ii)
29 | ownership of fifty percent (50%) or more of the outstanding shares, or (iii)
30 | beneficial ownership of such entity.
31 |
32 |
33 |
34 | "You" (or "Your") shall mean
35 | an individual or Legal Entity exercising permissions granted by this License.
36 |
37 |
38 |
39 |
40 | "Source" form shall mean the preferred form for making modifications,
41 | including but not limited to software source code, documentation source, and
42 | configuration files.
43 |
44 |
45 |
46 | "Object" form shall mean any form resulting
47 | from mechanical transformation or translation of a Source form, including but not
48 | limited to compiled object code, generated documentation, and conversions to
49 | other media types.
50 |
51 |
52 |
53 | "Work" shall mean the work of authorship,
54 | whether in Source or Object form, made available under the License, as indicated
55 | by a copyright notice that is included in or attached to the work (an example is
56 | provided in the Appendix below).
57 |
58 |
59 |
60 | "Derivative Works" shall mean any
61 | work, whether in Source or Object form, that is based on (or derived from) the
62 | Work and for which the editorial revisions, annotations, elaborations, or other
63 | modifications represent, as a whole, an original work of authorship. For the
64 | purposes of this License, Derivative Works shall not include works that remain
65 | separable from, or merely link (or bind by name) to the interfaces of, the Work
66 | and Derivative Works thereof.
67 |
68 |
69 |
70 | "Contribution" shall mean any work
71 | of authorship, including the original version of the Work and any modifications
72 | or additions to that Work or Derivative Works thereof, that is intentionally
73 | submitted to Licensor for inclusion in the Work by the copyright owner or by an
74 | individual or Legal Entity authorized to submit on behalf of the copyright owner.
75 | For the purposes of this definition, "submitted" means any form of electronic,
76 | verbal, or written communication sent to the Licensor or its representatives,
77 | including but not limited to communication on electronic mailing lists, source
78 | code control systems, and issue tracking systems that are managed by, or on
79 | behalf of, the Licensor for the purpose of discussing and improving the Work, but
80 | excluding communication that is conspicuously marked or otherwise designated in
81 | writing by the copyright owner as "Not a Contribution."
82 |
83 |
84 |
85 |
86 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of
87 | whom a Contribution has been received by Licensor and subsequently incorporated
88 | within the Work.
89 |
90 | 2. Grant of Copyright License. Subject to the terms and
91 | conditions of this License, each Contributor hereby grants to You a perpetual,
92 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license
93 | to reproduce, prepare Derivative Works of, publicly display, publicly perform,
94 | sublicense, and distribute the Work and such Derivative Works in Source or Object
95 | form.
96 |
97 | 3. Grant of Patent License. Subject to the terms and conditions of this
98 | License, each Contributor hereby grants to You a perpetual, worldwide,
99 | non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this
100 | section) patent license to make, have made, use, offer to sell, sell, import, and
101 | otherwise transfer the Work, where such license applies only to those patent
102 | claims licensable by such Contributor that are necessarily infringed by their
103 | Contribution(s) alone or by combination of their Contribution(s) with the Work to
104 | which such Contribution(s) was submitted. If You institute patent litigation
105 | against any entity (including a cross-claim or counterclaim in a lawsuit)
106 | alleging that the Work or a Contribution incorporated within the Work constitutes
107 | direct or contributory patent infringement, then any patent licenses granted to
108 | You under this License for that Work shall terminate as of the date such
109 | litigation is filed.
110 |
111 | 4. Redistribution. You may reproduce and distribute
112 | copies of the Work or Derivative Works thereof in any medium, with or without
113 | modifications, and in Source or Object form, provided that You meet the following
114 | conditions:
115 |
116 | (a) You must give any other recipients of the Work or
117 | Derivative Works a copy of this License; and
118 |
119 | (b) You must cause any
120 | modified files to carry prominent notices stating that You changed the files;
121 | and
122 |
123 | (c) You must retain, in the Source form of any Derivative Works that
124 | You distribute, all copyright, patent, trademark, and attribution notices from
125 | the Source form of the Work, excluding those notices that do not pertain to any
126 | part of the Derivative Works; and
127 |
128 | (d) If the Work includes a "NOTICE" text
129 | file as part of its distribution, then any Derivative Works that You distribute
130 | must include a readable copy of the attribution notices contained within such
131 | NOTICE file, excluding those notices that do not pertain to any part of the
132 | Derivative Works, in at least one of the following places: within a NOTICE text
133 | file distributed as part of the Derivative Works; within the Source form or
134 | documentation, if provided along with the Derivative Works; or, within a display
135 | generated by the Derivative Works, if and wherever such third-party notices
136 | normally appear. The contents of the NOTICE file are for informational purposes
137 | only and do not modify the License. You may add Your own attribution notices
138 | within Derivative Works that You distribute, alongside or as an addendum to the
139 | NOTICE text from the Work, provided that such additional attribution notices
140 | cannot be construed as modifying the License.
141 |
142 | You may add Your own
143 | copyright statement to Your modifications and may provide additional or different
144 | license terms and conditions for use, reproduction, or distribution of Your
145 | modifications, or for any such Derivative Works as a whole, provided Your use,
146 | reproduction, and distribution of the Work otherwise complies with the conditions
147 | stated in this License.
148 |
149 | 5. Submission of Contributions. Unless You explicitly
150 | state otherwise, any Contribution intentionally submitted for inclusion in the
151 | Work by You to the Licensor shall be under the terms and conditions of this
152 | License, without any additional terms or conditions. Notwithstanding the above,
153 | nothing herein shall supersede or modify the terms of any separate license
154 | agreement you may have executed with Licensor regarding such Contributions.
155 |
156 |
157 | 6. Trademarks. This License does not grant permission to use the trade names,
158 | trademarks, service marks, or product names of the Licensor, except as required
159 | for reasonable and customary use in describing the origin of the Work and
160 | reproducing the content of the NOTICE file.
161 |
162 | 7. Disclaimer of Warranty. Unless
163 | required by applicable law or agreed to in writing, Licensor provides the Work
164 | (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT
165 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including,
166 | without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT,
167 | MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible
168 | for determining the appropriateness of using or redistributing the Work and
169 | assume any risks associated with Your exercise of permissions under this
170 | License.
171 |
172 | 8. Limitation of Liability. In no event and under no legal theory,
173 | whether in tort (including negligence), contract, or otherwise, unless required
174 | by applicable law (such as deliberate and grossly negligent acts) or agreed to in
175 | writing, shall any Contributor be liable to You for damages, including any
176 | direct, indirect, special, incidental, or consequential damages of any character
177 | arising as a result of this License or out of the use or inability to use the
178 | Work (including but not limited to damages for loss of goodwill, work stoppage,
179 | computer failure or malfunction, or any and all other commercial damages or
180 | losses), even if such Contributor has been advised of the possibility of such
181 | damages.
182 |
183 | 9. Accepting Warranty or Additional Liability. While redistributing
184 | the Work or Derivative Works thereof, You may choose to offer, and charge a fee
185 | for, acceptance of support, warranty, indemnity, or other liability obligations
186 | and/or rights consistent with this License. However, in accepting such
187 | obligations, You may act only on Your own behalf and on Your sole responsibility,
188 | not on behalf of any other Contributor, and only if You agree to indemnify,
189 | defend, and hold each Contributor harmless for any liability incurred by, or
190 | claims asserted against, such Contributor by reason of your accepting any such
191 | warranty or additional liability. END OF TERMS AND CONDITIONS
192 |
193 | APPENDIX: How to
194 | apply the Apache License to your work.
195 |
196 | To apply the Apache License to your work,
197 | attach the following boilerplate notice, with the fields enclosed by brackets
198 | "[]" replaced with your own identifying information. (Don't include the
199 | brackets!) The text should be enclosed in the appropriate comment syntax for the
200 | file format. We also recommend that a file or class name and description of
201 | purpose be included on the same "printed page" as the copyright notice for easier
202 | identification within third-party archives.
203 |
204 | Copyright [yyyy] Steve
205 | Goode
206 |
207 | Licensed under the Apache License, Version 2.0 (the "License");
208 |
209 | you may
210 | not use this file except in compliance with the License.
211 |
212 | You may obtain a copy
213 | of the License at
214 |
215 | http://www.apache.org/licenses/LICENSE-2.0
216 |
217 | Unless required by
218 | applicable law or agreed to in writing, software
219 |
220 | distributed under the License
221 | is distributed on an "AS IS" BASIS,
222 |
223 | WITHOUT WARRANTIES OR CONDITIONS OF ANY
224 | KIND, either express or implied.
225 |
226 | See the License for the specific language
227 | governing permissions and
228 |
229 | limitations under the License.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://github.com/nearform/playwright-firebase/actions/workflows/ci.yml)
2 |
3 | # @nearform/playwright-firebase
4 |
5 | > [!NOTE]
6 | > This is an ESM only package, please make sure your usage follows the rules of ESM
7 | > User the following [guide](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c#pure-esm-package) to learn more
8 |
9 | Tidy way to authenticate Playwright E2E tests on Firebase.
10 |
11 | Install using npm:
12 |
13 | ```bash
14 | npm install @nearform/playwright-firebase
15 | ```
16 |
17 | or yarn:
18 |
19 | ```bash
20 | yarn add @nearform/playwright-firebase
21 | ```
22 |
23 | Want to see it in action? Go to [Example](#example) to try it out!
24 |
25 | ## Contents
26 |
27 | 1. [Setup](#setup)
28 | 2. [Motivation](#motivation)
29 | 3. [Example](#example)
30 |
31 |
32 |
33 | ## Setup
34 |
35 | ### Firebase environment variables
36 |
37 | To set up this plugin you will need three sensitive environment variables in order to authenticate with Firebase. These are:
38 |
39 | 1. [Firebase Service Account](https://firebase.google.com/docs/app-distribution/authenticate-service-account)
40 | 2. [Firebase User ID](https://firebase.google.com/docs/auth/web/manage-users)
41 | 3. [Firebase Configurations](https://support.google.com/firebase/answer/7015592?hl=en#zippy=%2Cin-this-article)
42 |
43 | For more information about Firebase you can read the documentation [here](https://firebase.google.com/docs/auth/web/start)
44 |
45 | It's recommended to place these values in a `.env` file. For clarity, the Firebase User ID is often abbreviated to UID, as you will find below. The plugin accepts
46 |
47 | - Service Account: JSON
48 | - UID: string
49 | - Firebase Configurations: JSON
50 |
51 | you don't need to place quotes around these environment variables.
52 |
53 | ### Attaching playright-firebase as a fixture to Playwright
54 |
55 | Playwright is based on fixtures. You have likely already used them within Playwright, they are the `{ page }` object that is passed in to `test`. More information on them [here](https://playwright.dev/docs/test-fixtures). In the very same way, we are able to add our own fixture, which we call `auth` to the tests. To do so, we need to create a setup file that will automatically run before all other tests. We will call this `auth.setup.ts`
56 |
57 | ```ts
58 | // auth.setup.ts
59 | import playwrightFirebasePlugin from '@nearform/playwright-firebase'
60 | import { test as base } from '@playwright/test'
61 |
62 | const serviceAccount = JSON.parse(process.env.SERVICE_ACCOUNT!)
63 | const uid = process.env.REACT_APP_UID!
64 | const options = JSON.parse(process.env.REACT_APP_FIREBASE_CONFIG!)
65 | export const test = playwrightFirebasePlugin(serviceAccount, options, uid, base)
66 | ```
67 |
68 | Above we import the test directly from `@playwright/test` as `base` and then export a new `test` object which is identical to `base` with the addition of a fixture called `auth`. An important note is that we should now import `test` from this file instead of `@playwright/test`.
69 |
70 | ```ts
71 | //example.spec.ts
72 | import { expect } from '@playwright/test'
73 | import { test } from '../auth.setup' // <----- here we import test from our auth.setup.ts.
74 | import { Page } from '@playwright/test'
75 |
76 | // We now access auth in exactly the same method as we do page.
77 | test('has title', async ({ page, auth }: { page: Page; auth: any }) => {
78 | await page.goto('/', { waitUntil: 'networkidle' })
79 | await auth.login(page) // <-- we need to pass in the page object here.
80 |
81 | const txt = await page.getByText('Welcome! You are now logged in')
82 | await expect(txt).toBeVisible()
83 |
84 | await auth.logout(page)
85 |
86 | await expect(txt).not.toBeVisible()
87 | })
88 | ```
89 |
90 | It's recommended to use `await` for your `expect` assertions after logging in/out, as the Firebase authentication is likely tied to states that require re-rendering of your application.
91 |
92 | ### TypeScript
93 |
94 | If you're using Typescript, one small addition you'll need to make is to add the type `Credentials` to your `playwright.config.ts` such that
95 |
96 | ```ts
97 | import { Credentials } from '@nearform/playwright-firebase'
98 |
99 | export default defineConfig({
100 | ...
101 | })
102 | ```
103 |
104 |
105 |
106 | ## Motivation
107 |
108 | This package is built as a plugin for Playwright testing for the use-case of Firebase authentication. There are two methods of automating a login procedure in Playwright tests:
109 |
110 | 1. As a normal user would: inserting a real username and password into the intended fields.
111 | 2. Authenticating via the Firebase SDK directly
112 |
113 | This plugin was developed with the 2nd method in mind as it is
114 |
115 | - Provider agnostic: Does not need to know the specifics of the authentication provider
116 | - A faster way of logging in, so you can focus on testing
117 | - Better security than using a username and password.
118 |
119 |
120 |
121 | ## Example
122 |
123 | Within this repo we have an `example/` folder that contains a sample React application for authenticating with the Google Provider. You'll need to setup the Firebase environment variables as described above in the setup section, but the rest is taken care of.
124 |
125 | 1. Clone this repository
126 | 2. `npm i`
127 | 3. `cd ./example`
128 | 4. `npm i`
129 | 5. `npm run start`
130 |
131 | At this point, you should see a web server running on `localhost:3000`. If your screen is blank, check the console on your browser for any error messages. It's likely that you haven't place the `.env` file in the right location, or that you haven't filled it in correctly.
132 |
133 | 6. Make a `.env` file within `./example`, copy and paste over the variable names from `.env.sample` and populate them with your real Firebase environment variables
134 | 7. Run `npx playwright test`
135 |
136 | [](https://www.nearform.com/contact/?utm_source=open-source&utm_medium=banner&utm_campaign=os-project-pages)
137 |
--------------------------------------------------------------------------------
/babel.config.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | ['@babel/preset-env', { targets: { node: 'current' } }],
4 | '@babel/preset-typescript',
5 | ],
6 | };
--------------------------------------------------------------------------------
/example/.env.sample:
--------------------------------------------------------------------------------
1 | REACT_APP_FIREBASE_CONFIG=
2 | REACT_APP_UID=
3 | SERVICE_ACCOUNT=
4 |
--------------------------------------------------------------------------------
/example/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env
17 | .env.local
18 | .env.development.local
19 | .env.test.local
20 | .env.production.local
21 |
22 | npm-debug.log*
23 | yarn-debug.log*
24 | yarn-error.log*
25 | /test-results/
26 | /playwright-report/
27 | /playwright/.cache/
28 |
--------------------------------------------------------------------------------
/example/README.md:
--------------------------------------------------------------------------------
1 | # Getting Started with Create React App
2 |
3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
4 |
5 | ## Available Scripts
6 |
7 | In the project directory, you can run:
8 |
9 | ### `npm start`
10 |
11 | Runs the app in the development mode.\
12 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
13 |
14 | The page will reload if you make edits.\
15 | You will also see any lint errors in the console.
16 |
17 | ### `npm test`
18 |
19 | Launches the test runner in the interactive watch mode.\
20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
21 |
22 | ### `npm run build`
23 |
24 | Builds the app for production to the `build` folder.\
25 | It correctly bundles React in production mode and optimizes the build for the best performance.
26 |
27 | The build is minified and the filenames include the hashes.\
28 | Your app is ready to be deployed!
29 |
30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
31 |
32 | ### `npm run eject`
33 |
34 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!**
35 |
36 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
37 |
38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
39 |
40 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
41 |
42 | ## Learn More
43 |
44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
45 |
46 | To learn React, check out the [React documentation](https://reactjs.org/).
47 |
--------------------------------------------------------------------------------
/example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example",
3 | "version": "0.1.0",
4 | "type": "module",
5 | "private": true,
6 | "dependencies": {
7 | "@testing-library/jest-dom": "^5.17.0",
8 | "@testing-library/react": "^13.4.0",
9 | "@testing-library/user-event": "^13.5.0",
10 | "@types/jest": "^27.5.2",
11 | "@types/node": "^16.18.59",
12 | "@types/react": "^18.2.29",
13 | "@types/react-dom": "^18.2.14",
14 | "dotenv": "^16.3.1",
15 | "playwright": "^1.39.0",
16 | "react": "^18.2.0",
17 | "react-dom": "^18.2.0",
18 | "react-scripts": "5.0.1",
19 | "typescript": "^4.9.5",
20 | "web-vitals": "^2.1.4"
21 | },
22 | "scripts": {
23 | "start": "react-scripts start",
24 | "build": "react-scripts build",
25 | "test": "react-scripts test",
26 | "eject": "react-scripts eject"
27 | },
28 | "eslintConfig": {
29 | "extends": [
30 | "react-app",
31 | "react-app/jest"
32 | ]
33 | },
34 | "browserslist": {
35 | "production": [
36 | ">0.2%",
37 | "not dead",
38 | "not op_mini all"
39 | ],
40 | "development": [
41 | "last 1 chrome version",
42 | "last 1 firefox version",
43 | "last 1 safari version"
44 | ]
45 | },
46 | "devDependencies": {
47 | "@playwright/test": "^1.39.0"
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/example/playwright.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig, devices } from '@playwright/test'
2 | import { Credentials } from '@nearform/playwright-firebase'
3 | /**
4 | * Read environment variables from file.
5 | * https://github.com/motdotla/dotenv
6 | */
7 | // require('dotenv').config();
8 |
9 | /**
10 | * See https://playwright.dev/docs/test-configuration.
11 | */
12 | export default defineConfig({
13 | testDir: './test-examples/',
14 | testIgnore: '*.setup.ts',
15 | /* Run tests in files in parallel */
16 | fullyParallel: true,
17 | /* Fail the build on CI if you accidentally left test.only in the source code. */
18 | forbidOnly: !!process.env.CI,
19 | /* Retry on CI only */
20 | retries: process.env.CI ? 2 : 0,
21 | /* Opt out of parallel tests on CI. */
22 | workers: process.env.CI ? 1 : undefined,
23 | /* Reporter to use. See https://playwright.dev/docs/test-reporters */
24 | reporter: 'html',
25 | /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
26 | use: {
27 | /* Base URL to use in actions like `await page.goto('/')`. */
28 | baseURL: 'http://127.0.0.1:3000',
29 | video: 'on',
30 | /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
31 | trace: 'on-first-retry'
32 | },
33 |
34 | /* Configure projects for major browsers */
35 | projects: [
36 | {
37 | name: 'chromium',
38 | use: { ...devices['Desktop Chrome'] }
39 | },
40 |
41 | {
42 | name: 'firefox',
43 | use: { ...devices['Desktop Firefox'] }
44 | },
45 |
46 | {
47 | name: 'webkit',
48 | use: { ...devices['Desktop Safari'] }
49 | }
50 | ],
51 | webServer: {
52 | command: 'npm run start',
53 | url: 'http://127.0.0.1:3000',
54 | reuseExistingServer: !process.env.CI
55 | }
56 | })
57 |
--------------------------------------------------------------------------------
/example/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nearform/playwright-firebase/78cbcbcdf7a2cb8a8d0081649baa9d61023a781c/example/public/favicon.ico
--------------------------------------------------------------------------------
/example/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/example/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nearform/playwright-firebase/78cbcbcdf7a2cb8a8d0081649baa9d61023a781c/example/public/logo192.png
--------------------------------------------------------------------------------
/example/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nearform/playwright-firebase/78cbcbcdf7a2cb8a8d0081649baa9d61023a781c/example/public/logo512.png
--------------------------------------------------------------------------------
/example/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/example/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/example/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | h1 {
6 | text-align: center;
7 | }
8 |
9 | .user-input {
10 | display: flex;
11 | flex-direction: column;
12 | align-items: center;
13 | background-color: #2aabcf;
14 | padding: 10px;
15 | margin-left: 50px;
16 | margin-right: 50px;
17 | border: solid 4px black;
18 | border-radius: 20px;
19 | }
20 |
21 | button {
22 | height: 50px;
23 | width: 100px;
24 | background-color: white;
25 | border-radius: 5px;
26 | font-size: 20px;
27 | }
28 | .username {
29 | color: white;
30 | font-size: 20px;
31 | }
32 |
33 | .App-logo {
34 | height: 40vmin;
35 | pointer-events: none;
36 | }
37 |
38 | @media (prefers-reduced-motion: no-preference) {
39 | .App-logo {
40 | animation: App-logo-spin infinite 20s linear;
41 | }
42 | }
43 |
44 | .App-header {
45 | background-color: #282c34;
46 | min-height: 100vh;
47 | display: flex;
48 | flex-direction: column;
49 | align-items: center;
50 | justify-content: center;
51 | font-size: calc(10px + 2vmin);
52 | color: white;
53 | }
54 |
55 | .App-link {
56 | color: #61dafb;
57 | }
58 |
59 | @keyframes App-logo-spin {
60 | from {
61 | transform: rotate(0deg);
62 | }
63 | to {
64 | transform: rotate(360deg);
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/example/src/App.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render, screen } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | render();
7 | const linkElement = screen.getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/example/src/App.tsx:
--------------------------------------------------------------------------------
1 | import useAuth from './hooks/useAuth'
2 | import './App.css'
3 | function App() {
4 | const { user, login, logout } = useAuth()
5 | const buttonText = !user ? 'Log in' : 'Log out'
6 | const handleLoginOut = () => {
7 | if (user) {
8 | logout()
9 | return
10 | }
11 | login()
12 | }
13 | return (
14 | <>
15 |
25 | If you're unfamiliar with Firebase please read{' '}
26 |
27 | the documentation
28 | {' '}
29 | on using Firebase SDK. You can find additional information on the README{' '}
30 | here.{' '}
31 |
32 |
33 | You'll need to populate you .env file with your
34 |
59 | * Follow the instructions on the UID related to navigating to the
60 | Firebase console.
61 |
62 |
63 | Below we have some text that either shows the users displayed name, or
64 | "Logged out" depending on whether you've logged in with the button below
65 |
66 |
67 |
Try logging in! It will open a popup to sign in with Google.