diff --git a/.dockerignore b/.dockerignore
deleted file mode 100644
index 3c3629e6..00000000
--- a/.dockerignore
+++ /dev/null
@@ -1 +0,0 @@
-node_modules
diff --git a/.eslintignore b/.eslintignore
index 2d3c911c..d9a31998 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -1,5 +1,6 @@
**/node_modules/*
dist
+cypress.config.ts
coverage
**/.next/*
*.json
diff --git a/.eslintrc.json b/.eslintrc.json
index d26019a2..cbe13564 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -8,7 +8,7 @@
"ecmaVersion": "latest",
"sourceType": "module"
},
- "plugins": ["@typescript-eslint", "import"],
+ "plugins": ["@typescript-eslint", "import", "no-relative-import-paths"],
"extends": [
"plugin:import/recommended",
"plugin:import/typescript",
@@ -33,12 +33,20 @@
],
"react/function-component-definition": [
2,
- { "namedComponents": "function-declaration" }
+ {
+ "namedComponents": "function-declaration"
+ }
],
"react/destructuring-assignment": [2, "always"],
"react/button-has-type": 2,
"react/no-array-index-key": 2,
"import/order": 2,
+ "no-relative-import-paths/no-relative-import-paths": [
+ "error",
+ {
+ "allowSameFolder": true
+ }
+ ],
"semi": [2, "always"],
"quotes": [2, "double"],
"prefer-destructuring": [
@@ -61,12 +69,23 @@
"arrow-body-style": [2, "as-needed"],
"arrow-parens": [2, "always"],
"space-infix-ops": 2,
- "arrow-spacing": [2, { "before": true, "after": true }],
- "no-unused-vars": [2, { "args": "all", "argsIgnorePattern": "_" }],
+ "arrow-spacing": [
+ 2,
+ {
+ "before": true,
+ "after": true
+ }
+ ],
+ "no-unused-vars": [
+ 2,
+ {
+ "args": "all",
+ "argsIgnorePattern": "_"
+ }
+ ],
"guard-for-in": 2,
"no-await-in-loop": 2,
"indent": [2, 2],
- "object-curly-newline": [2, { "minProperties": 4, "consistent": true }],
"brace-style": 2,
"no-multiple-empty-lines": 2,
"eol-last": [2, "always"],
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 00000000..dd84ea78
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,38 @@
+---
+name: Bug report
+about: Create a report to help us improve
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+**To Reproduce**
+Steps to reproduce the behavior:
+1. Go to '...'
+2. Click on '....'
+3. Scroll down to '....'
+4. See error
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Screenshots**
+If applicable, add screenshots to help explain your problem.
+
+**Desktop (please complete the following information):**
+ - OS: [e.g. iOS]
+ - Browser [e.g. chrome, safari]
+ - Version [e.g. 22]
+
+**Smartphone (please complete the following information):**
+ - Device: [e.g. iPhone6]
+ - OS: [e.g. iOS8.1]
+ - Browser [e.g. stock browser, safari]
+ - Version [e.g. 22]
+
+**Additional context**
+Add any other context about the problem here.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 00000000..bbcbbe7d
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,20 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+**Is your feature request related to a problem? Please describe.**
+A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+
+**Describe the solution you'd like**
+A clear and concise description of what you want to happen.
+
+**Describe alternatives you've considered**
+A clear and concise description of any alternative solutions or features you've considered.
+
+**Additional context**
+Add any other context or screenshots about the feature request here.
diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml
deleted file mode 100644
index 56c484af..00000000
--- a/.github/workflows/preview.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-name: Deploy to Vercel Preview
-env:
- VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
- VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
-on:
- workflow_dispatch:
- push:
- branches:
- - premium-strip
-
-jobs:
- deploy:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- - name: install Vercel CLI
- run: npm install --global vercel@latest
- - name: pull Vercel environment information
- run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}
- - name: build project artifacts
- run: vercel build --token=${{ secrets.VERCEL_TOKEN }}
- - name: deploy preview + assign beta domain
- run: |
- OUTPUT=$(du --inodes -d 5 .vercel/output)
- echo "$OUTPUT"
- LAST=$(echo "$OUTPUT" | tail -n 1)
- PERCENTAGE=$(echo "$LAST" | awk 'BEGIN {maxtotal=15000} { printf "%.2f%%", ($1/maxtotal*100) }')
- echo "Vercel file usage percentage" >> $GITHUB_STEP_SUMMARY
- echo "$PERCENTAGE" >> $GITHUB_STEP_SUMMARY
- du -h -d 3 .vercel/output/functions/en
- vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }} > domain.txt
- vercel alias --scope ${{ secrets.VERCEL_TEAM_ID }} --token ${{ secrets.VERCEL_TOKEN }} set `cat domain.txt` biodrop-preview.vercel.app
\ No newline at end of file
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index cba9c810..446ecd62 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -15,7 +15,7 @@ jobs:
- name: Set up Node.js
uses: actions/setup-node@v2
with:
- node-version: "18" # current LTS (we have 16 in Docker)
+ node-version: "18"
- name: Install dependencies
run: yarn install
@@ -27,4 +27,9 @@ jobs:
run: yarn test
- name: Run Cypress tests
- run: yarn cypress
+ run: |
+ if [[ ${{ github.event.pull_request.base.ref }} == 'main' ]]; then
+ yarn cypress
+ else
+ echo "Skipping Cypress tests for non-main branch."
+ fi
diff --git a/.gitignore b/.gitignore
index 45c1abce..103c6c18 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,7 @@
# testing
/coverage
+/cypress/screenshots
# next.js
/.next/
diff --git a/.husky/pre-push b/.husky/pre-push
index 07c67d33..c2162796 100644
--- a/.husky/pre-push
+++ b/.husky/pre-push
@@ -3,3 +3,4 @@
yarn prettier
yarn lint
+yarn cypress
diff --git a/Dockerfile.dev b/Dockerfile.dev
deleted file mode 100644
index 04fbf3d1..00000000
--- a/Dockerfile.dev
+++ /dev/null
@@ -1,15 +0,0 @@
-FROM node:16-alpine
-
-WORKDIR /usr/src/app
-
-COPY ./package*.json ./
-
-COPY prisma ./prisma/
-
-COPY .env ./
-
-RUN yarn install
-
-COPY ./ ./
-
-CMD ["yarn", "dev"]
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 00000000..f288702d
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/README.md b/README.md
index bdca1c59..851d5439 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,6 @@ First we need to have yarn installed on your computer, to do so, run the followi
```bash
npm install --global yarn
```
-
To install all the project dependencies, inside the project's root folder, run the following in the command line
```bash
@@ -13,86 +12,10 @@ yarn
Create a `.env` file at the root of your project using the `.env.example` file to know which keys to add
-
-Add these env variables specifically (it's important to have exactly the same because of how docker is configured):
-```
-DATABASE_URL=postgresql://chingu:chingu@chingu:5433/dashboard?schema=public
-HOSTNAME=chingu
-POSTGRES_USER=chingu
-POSTGRES_PASSWORD=chingu
-POSTGRES_DB=dashboard
-PGADMIN_EMAIL=chinguadmin@chingu.com
-PGADMIN_PW=chingu5432
-```
-
-Run these commands when starting up your project:
-
-```
-docker compose build
-docker compose up
-```
-
-Open a 2nd terminal window and run these commands:
-
-```
-docker ps
-docker exec -it sh
-npx prisma migrate dev
-```
-
-Docker ps should list 3 containers (assuming you're not running anything else). If you have more, you can just look for 3 that were created recently. The
-id you want should be under a image name of something like chingu-dashboard_app (it should be whatyounamedyourprojectfolder-app). The other 2 image names will have pgadmin and postgres in it (look for the one without
-those in its name).
-
-If you have docker desktop, you can just use the cli in the app container using the gui (way easier).
-
-To open pgadmin, go to localhost:4000. Put in the credentials, as written in the .env file. Again, if you have docker desktop, you can just open from the gui.
-
-To run prisma studio, follow the same steps above to invoke a command inside your docker container.
-
-```
-docker ps (to find the id of your container)
-docker exec -it sh
-npx prisma studio
-```
-
-**It is important to run your migration before running prisma studio or it will error**
-
-You can access prisma studio at localhost:5555
-
-When done with your session, run the following command:
-
-```
-docker compose down
-```
-
-This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
-
-## Getting Started
-
-First, run the development server:
+To run the development server:
```bash
yarn dev
```
-Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
-
-You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
-
-This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
-
-## Learn More
-
-To learn more about Next.js, take a look at the following resources:
-
-- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
-- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
-
-You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
-
-## Deploy on Vercel
-
-The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
-
-Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
+Open [http://localhost:3000](http://localhost:3000)
diff --git a/cypress/e2e/2-advanced-examples/aliasing.cy.js b/cypress/e2e/2-advanced-examples/aliasing.cy.js
deleted file mode 100644
index cbf76104..00000000
--- a/cypress/e2e/2-advanced-examples/aliasing.cy.js
+++ /dev/null
@@ -1,43 +0,0 @@
-///
-
-context("Aliasing", () => {
- beforeEach(() => {
- cy.visit("https://example.cypress.io/commands/aliasing");
- });
-
- it(".as() - alias a DOM element for later use", () => {
- // https://on.cypress.io/as
-
- // Alias a DOM element for use later
- // We don't have to traverse to the element
- // later in our code, we reference it with @
-
- cy.get(".as-table")
- .find("tbody>tr")
- .first()
- .find("td")
- .first()
- .find("button")
- .as("firstBtn");
-
- // when we reference the alias, we place an
- // @ in front of its name
- cy.get("@firstBtn").click();
-
- cy.get("@firstBtn")
- .should("have.class", "btn-success")
- .and("contain", "Changed");
- });
-
- it(".as() - alias a route for later use", () => {
- // Alias the route to wait for its response
- cy.intercept("GET", "**/comments/*").as("getComment");
-
- // we have code that gets a comment when
- // the button is clicked in scripts.js
- cy.get(".network-btn").click();
-
- // https://on.cypress.io/wait
- cy.wait("@getComment").its("response.statusCode").should("eq", 200);
- });
-});
diff --git a/cypress/e2e/2-advanced-examples/assertions.cy.js b/cypress/e2e/2-advanced-examples/assertions.cy.js
deleted file mode 100644
index a93512cc..00000000
--- a/cypress/e2e/2-advanced-examples/assertions.cy.js
+++ /dev/null
@@ -1,175 +0,0 @@
-///
-
-context("Assertions", () => {
- beforeEach(() => {
- cy.visit("https://example.cypress.io/commands/assertions");
- });
-
- describe("Implicit Assertions", () => {
- it(".should() - make an assertion about the current subject", () => {
- // https://on.cypress.io/should
- cy.get(".assertion-table")
- .find("tbody tr:last")
- .should("have.class", "success")
- .find("td")
- .first()
- // checking the text of the
element in various ways
- .should("have.text", "Column content")
- .should("contain", "Column content")
- .should("have.html", "Column content")
- // chai-jquery uses "is()" to check if element matches selector
- .should("match", "td")
- // to match text content against a regular expression
- // first need to invoke jQuery method text()
- // and then match using regular expression
- .invoke("text")
- .should("match", /column content/i);
-
- // a better way to check element's text content against a regular expression
- // is to use "cy.contains"
- // https://on.cypress.io/contains
- cy.get(".assertion-table")
- .find("tbody tr:last")
- // finds first
element with text content matching regular expression
- .contains("td", /column content/i)
- .should("be.visible");
-
- // for more information about asserting element's text
- // see https://on.cypress.io/using-cypress-faq#How-do-I-get-an-element’s-text-contents
- });
-
- it(".and() - chain multiple assertions together", () => {
- // https://on.cypress.io/and
- cy.get(".assertions-link")
- .should("have.class", "active")
- .and("have.attr", "href")
- .and("include", "cypress.io");
- });
- });
-
- describe("Explicit Assertions", () => {
- // https://on.cypress.io/assertions
- it("expect - make an assertion about a specified subject", () => {
- // We can use Chai's BDD style assertions
- expect(true).to.be.true;
- const o = { foo: "bar" };
-
- expect(o).to.equal(o);
- expect(o).to.deep.equal({ foo: "bar" });
- // matching text using regular expression
- expect("FooBar").to.match(/bar$/i);
- });
-
- it("pass your own callback function to should()", () => {
- // Pass a function to should that can have any number
- // of explicit assertions within it.
- // The ".should(cb)" function will be retried
- // automatically until it passes all your explicit assertions or times out.
- cy.get(".assertions-p")
- .find("p")
- .should(($p) => {
- // https://on.cypress.io/$
- // return an array of texts from all of the p's
- const texts = $p.map((i, el) => Cypress.$(el).text());
-
- // jquery map returns jquery object
- // and .get() convert this to simple array
- const paragraphs = texts.get();
-
- // array should have length of 3
- expect(paragraphs, "has 3 paragraphs").to.have.length(3);
-
- // use second argument to expect(...) to provide clear
- // message with each assertion
- expect(paragraphs, "has expected text in each paragraph").to.deep.eq([
- "Some text from first p",
- "More text from second p",
- "And even more text from third p",
- ]);
- });
- });
-
- it("finds element by class name regex", () => {
- cy.get(".docs-header")
- .find("div")
- // .should(cb) callback function will be retried
- .should(($div) => {
- expect($div).to.have.length(1);
-
- const className = $div[0].className;
-
- expect(className).to.match(/heading-/);
- })
- // .then(cb) callback is not retried,
- // it either passes or fails
- .then(($div) => {
- expect($div, "text content").to.have.text("Introduction");
- });
- });
-
- it("can throw any error", () => {
- cy.get(".docs-header")
- .find("div")
- .should(($div) => {
- if ($div.length !== 1) {
- // you can throw your own errors
- throw new Error("Did not find 1 element");
- }
-
- const className = $div[0].className;
-
- if (!className.match(/heading-/)) {
- throw new Error(`Could not find class "heading-" in ${className}`);
- }
- });
- });
-
- it("matches unknown text between two elements", () => {
- /**
- * Text from the first element.
- * @type {string}
- */
- let text;
-
- /**
- * Normalizes passed text,
- * useful before comparing text with spaces and different capitalization.
- * @param {string} s Text to normalize
- */
- const normalizeText = (s) => s.replace(/\s/g, "").toLowerCase();
-
- cy.get(".two-elements")
- .find(".first")
- .then(($first) => {
- // save text from the first element
- text = normalizeText($first.text());
- });
-
- cy.get(".two-elements")
- .find(".second")
- .should(($div) => {
- // we can massage text before comparing
- const secondText = normalizeText($div.text());
-
- expect(secondText, "second text").to.equal(text);
- });
- });
-
- it("assert - assert shape of an object", () => {
- const person = {
- name: "Joe",
- age: 20,
- };
-
- assert.isObject(person, "value is object");
- });
-
- it("retries the should callback until assertions pass", () => {
- cy.get("#random-number").should(($div) => {
- const n = parseFloat($div.text());
-
- expect(n).to.be.gte(1).and.be.lte(10);
- });
- });
- });
-});
diff --git a/cypress/e2e/2-advanced-examples/connectors.cy.js b/cypress/e2e/2-advanced-examples/connectors.cy.js
deleted file mode 100644
index aaabcd13..00000000
--- a/cypress/e2e/2-advanced-examples/connectors.cy.js
+++ /dev/null
@@ -1,96 +0,0 @@
-///
-
-context("Connectors", () => {
- beforeEach(() => {
- cy.visit("https://example.cypress.io/commands/connectors");
- });
-
- it(".each() - iterate over an array of elements", () => {
- // https://on.cypress.io/each
- cy.get(".connectors-each-ul>li").each(($el, index, $list) => {
- console.log($el, index, $list);
- });
- });
-
- it(".its() - get properties on the current subject", () => {
- // https://on.cypress.io/its
- cy.get(".connectors-its-ul>li")
- // calls the 'length' property yielding that value
- .its("length")
- .should("be.gt", 2);
- });
-
- it(".invoke() - invoke a function on the current subject", () => {
- // our div is hidden in our script.js
- // $('.connectors-div').hide()
- cy.get(".connectors-div").should("be.hidden");
-
- // https://on.cypress.io/invoke
- // call the jquery method 'show' on the 'div.container'
- cy.get(".connectors-div").invoke("show");
-
- cy.get(".connectors-div").should("be.visible");
- });
-
- it(".spread() - spread an array as individual args to callback function", () => {
- // https://on.cypress.io/spread
- const arr = ["foo", "bar", "baz"];
-
- cy.wrap(arr).spread((foo, bar, baz) => {
- expect(foo).to.eq("foo");
- expect(bar).to.eq("bar");
- expect(baz).to.eq("baz");
- });
- });
-
- describe(".then()", () => {
- it("invokes a callback function with the current subject", () => {
- // https://on.cypress.io/then
- cy.get(".connectors-list > li").then(($lis) => {
- expect($lis, "3 items").to.have.length(3);
- expect($lis.eq(0), "first item").to.contain("Walk the dog");
- expect($lis.eq(1), "second item").to.contain("Feed the cat");
- expect($lis.eq(2), "third item").to.contain("Write JavaScript");
- });
- });
-
- it("yields the returned value to the next command", () => {
- cy.wrap(1)
- .then((num) => {
- expect(num).to.equal(1);
-
- return 2;
- })
- .then((num) => {
- expect(num).to.equal(2);
- });
- });
-
- it("yields the original subject without return", () => {
- cy.wrap(1)
- .then((num) => {
- expect(num).to.equal(1);
- // note that nothing is returned from this callback
- })
- .then((num) => {
- // this callback receives the original unchanged value 1
- expect(num).to.equal(1);
- });
- });
-
- it("yields the value yielded by the last Cypress command inside", () => {
- cy.wrap(1)
- .then((num) => {
- expect(num).to.equal(1);
- // note how we run a Cypress command
- // the result yielded by this Cypress command
- // will be passed to the second ".then"
- cy.wrap(2);
- })
- .then((num) => {
- // this callback receives the value yielded by "cy.wrap(2)"
- expect(num).to.equal(2);
- });
- });
- });
-});
diff --git a/cypress/e2e/2-advanced-examples/cookies.cy.js b/cypress/e2e/2-advanced-examples/cookies.cy.js
deleted file mode 100644
index d497107e..00000000
--- a/cypress/e2e/2-advanced-examples/cookies.cy.js
+++ /dev/null
@@ -1,122 +0,0 @@
-///
-
-context("Cookies", () => {
- beforeEach(() => {
- Cypress.Cookies.debug(true);
-
- cy.visit("https://example.cypress.io/commands/cookies");
-
- // clear cookies again after visiting to remove
- // any 3rd party cookies picked up such as cloudflare
- cy.clearCookies();
- });
-
- it("cy.getCookie() - get a browser cookie", () => {
- // https://on.cypress.io/getcookie
- cy.get("#getCookie .set-a-cookie").click();
-
- // cy.getCookie() yields a cookie object
- cy.getCookie("token").should("have.property", "value", "123ABC");
- });
-
- it("cy.getCookies() - get browser cookies for the current domain", () => {
- // https://on.cypress.io/getcookies
- cy.getCookies().should("be.empty");
-
- cy.get("#getCookies .set-a-cookie").click();
-
- // cy.getCookies() yields an array of cookies
- cy.getCookies()
- .should("have.length", 1)
- .should((cookies) => {
- // each cookie has these properties
- expect(cookies[0]).to.have.property("name", "token");
- expect(cookies[0]).to.have.property("value", "123ABC");
- expect(cookies[0]).to.have.property("httpOnly", false);
- expect(cookies[0]).to.have.property("secure", false);
- expect(cookies[0]).to.have.property("domain");
- expect(cookies[0]).to.have.property("path");
- });
- });
-
- it("cy.getAllCookies() - get all browser cookies", () => {
- // https://on.cypress.io/getallcookies
- cy.getAllCookies().should("be.empty");
-
- cy.setCookie("key", "value");
- cy.setCookie("key", "value", { domain: ".example.com" });
-
- // cy.getAllCookies() yields an array of cookies
- cy.getAllCookies()
- .should("have.length", 2)
- .should((cookies) => {
- // each cookie has these properties
- expect(cookies[0]).to.have.property("name", "key");
- expect(cookies[0]).to.have.property("value", "value");
- expect(cookies[0]).to.have.property("httpOnly", false);
- expect(cookies[0]).to.have.property("secure", false);
- expect(cookies[0]).to.have.property("domain");
- expect(cookies[0]).to.have.property("path");
-
- expect(cookies[1]).to.have.property("name", "key");
- expect(cookies[1]).to.have.property("value", "value");
- expect(cookies[1]).to.have.property("httpOnly", false);
- expect(cookies[1]).to.have.property("secure", false);
- expect(cookies[1]).to.have.property("domain", ".example.com");
- expect(cookies[1]).to.have.property("path");
- });
- });
-
- it("cy.setCookie() - set a browser cookie", () => {
- // https://on.cypress.io/setcookie
- cy.getCookies().should("be.empty");
-
- cy.setCookie("foo", "bar");
-
- // cy.getCookie() yields a cookie object
- cy.getCookie("foo").should("have.property", "value", "bar");
- });
-
- it("cy.clearCookie() - clear a browser cookie", () => {
- // https://on.cypress.io/clearcookie
- cy.getCookie("token").should("be.null");
-
- cy.get("#clearCookie .set-a-cookie").click();
-
- cy.getCookie("token").should("have.property", "value", "123ABC");
-
- // cy.clearCookies() yields null
- cy.clearCookie("token").should("be.null");
-
- cy.getCookie("token").should("be.null");
- });
-
- it("cy.clearCookies() - clear browser cookies for the current domain", () => {
- // https://on.cypress.io/clearcookies
- cy.getCookies().should("be.empty");
-
- cy.get("#clearCookies .set-a-cookie").click();
-
- cy.getCookies().should("have.length", 1);
-
- // cy.clearCookies() yields null
- cy.clearCookies();
-
- cy.getCookies().should("be.empty");
- });
-
- it("cy.clearAllCookies() - clear all browser cookies", () => {
- // https://on.cypress.io/clearallcookies
- cy.getAllCookies().should("be.empty");
-
- cy.setCookie("key", "value");
- cy.setCookie("key", "value", { domain: ".example.com" });
-
- cy.getAllCookies().should("have.length", 2);
-
- // cy.clearAllCookies() yields null
- cy.clearAllCookies();
-
- cy.getAllCookies().should("be.empty");
- });
-});
diff --git a/cypress/e2e/2-advanced-examples/cypress_api.cy.js b/cypress/e2e/2-advanced-examples/cypress_api.cy.js
deleted file mode 100644
index 2d5e7bf3..00000000
--- a/cypress/e2e/2-advanced-examples/cypress_api.cy.js
+++ /dev/null
@@ -1,197 +0,0 @@
-///
-
-context("Cypress APIs", () => {
- context("Cypress.Commands", () => {
- beforeEach(() => {
- cy.visit("https://example.cypress.io/cypress-api");
- });
-
- // https://on.cypress.io/custom-commands
-
- it(".add() - create a custom command", () => {
- Cypress.Commands.add(
- "console",
- {
- prevSubject: true,
- },
- (subject, method) => {
- // the previous subject is automatically received
- // and the commands arguments are shifted
-
- // allow us to change the console method used
- method = method || "log";
-
- // log the subject to the console
- console[method]("The subject is", subject);
-
- // whatever we return becomes the new subject
- // we don't want to change the subject so
- // we return whatever was passed in
- return subject;
- },
- );
-
- cy.get("button")
- .console("info")
- .then(($button) => {
- // subject is still $button
- });
- });
- });
-
- context("Cypress.Cookies", () => {
- beforeEach(() => {
- cy.visit("https://example.cypress.io/cypress-api");
- });
-
- // https://on.cypress.io/cookies
- it(".debug() - enable or disable debugging", () => {
- Cypress.Cookies.debug(true);
-
- // Cypress will now log in the console when
- // cookies are set or cleared
- cy.setCookie("fakeCookie", "123ABC");
- cy.clearCookie("fakeCookie");
- cy.setCookie("fakeCookie", "123ABC");
- cy.clearCookie("fakeCookie");
- cy.setCookie("fakeCookie", "123ABC");
- });
- });
-
- context("Cypress.arch", () => {
- beforeEach(() => {
- cy.visit("https://example.cypress.io/cypress-api");
- });
-
- it("Get CPU architecture name of underlying OS", () => {
- // https://on.cypress.io/arch
- expect(Cypress.arch).to.exist;
- });
- });
-
- context("Cypress.config()", () => {
- beforeEach(() => {
- cy.visit("https://example.cypress.io/cypress-api");
- });
-
- it("Get and set configuration options", () => {
- // https://on.cypress.io/config
- let myConfig = Cypress.config();
-
- expect(myConfig).to.have.property("animationDistanceThreshold", 5);
- expect(myConfig).to.have.property("baseUrl", null);
- expect(myConfig).to.have.property("defaultCommandTimeout", 4000);
- expect(myConfig).to.have.property("requestTimeout", 5000);
- expect(myConfig).to.have.property("responseTimeout", 30000);
- expect(myConfig).to.have.property("viewportHeight", 660);
- expect(myConfig).to.have.property("viewportWidth", 1000);
- expect(myConfig).to.have.property("pageLoadTimeout", 60000);
- expect(myConfig).to.have.property("waitForAnimations", true);
-
- expect(Cypress.config("pageLoadTimeout")).to.eq(60000);
-
- // this will change the config for the rest of your tests!
- Cypress.config("pageLoadTimeout", 20000);
-
- expect(Cypress.config("pageLoadTimeout")).to.eq(20000);
-
- Cypress.config("pageLoadTimeout", 60000);
- });
- });
-
- context("Cypress.dom", () => {
- beforeEach(() => {
- cy.visit("https://example.cypress.io/cypress-api");
- });
-
- // https://on.cypress.io/dom
- it(".isHidden() - determine if a DOM element is hidden", () => {
- let hiddenP = Cypress.$(".dom-p p.hidden").get(0);
- let visibleP = Cypress.$(".dom-p p.visible").get(0);
-
- // our first paragraph has css class 'hidden'
- expect(Cypress.dom.isHidden(hiddenP)).to.be.true;
- expect(Cypress.dom.isHidden(visibleP)).to.be.false;
- });
- });
-
- context("Cypress.env()", () => {
- beforeEach(() => {
- cy.visit("https://example.cypress.io/cypress-api");
- });
-
- // We can set environment variables for highly dynamic values
-
- // https://on.cypress.io/environment-variables
- it("Get environment variables", () => {
- // https://on.cypress.io/env
- // set multiple environment variables
- Cypress.env({
- host: "veronica.dev.local",
- api_server: "http://localhost:8888/v1/",
- });
-
- // get environment variable
- expect(Cypress.env("host")).to.eq("veronica.dev.local");
-
- // set environment variable
- Cypress.env("api_server", "http://localhost:8888/v2/");
- expect(Cypress.env("api_server")).to.eq("http://localhost:8888/v2/");
-
- // get all environment variable
- expect(Cypress.env()).to.have.property("host", "veronica.dev.local");
- expect(Cypress.env()).to.have.property(
- "api_server",
- "http://localhost:8888/v2/",
- );
- });
- });
-
- context("Cypress.log", () => {
- beforeEach(() => {
- cy.visit("https://example.cypress.io/cypress-api");
- });
-
- it("Control what is printed to the Command Log", () => {
- // https://on.cypress.io/cypress-log
- });
- });
-
- context("Cypress.platform", () => {
- beforeEach(() => {
- cy.visit("https://example.cypress.io/cypress-api");
- });
-
- it("Get underlying OS name", () => {
- // https://on.cypress.io/platform
- expect(Cypress.platform).to.be.exist;
- });
- });
-
- context("Cypress.version", () => {
- beforeEach(() => {
- cy.visit("https://example.cypress.io/cypress-api");
- });
-
- it("Get current version of Cypress being run", () => {
- // https://on.cypress.io/version
- expect(Cypress.version).to.be.exist;
- });
- });
-
- context("Cypress.spec", () => {
- beforeEach(() => {
- cy.visit("https://example.cypress.io/cypress-api");
- });
-
- it("Get current spec information", () => {
- // https://on.cypress.io/spec
- // wrap the object so we can inspect it easily by clicking in the command log
- cy.wrap(Cypress.spec).should("include.keys", [
- "name",
- "relative",
- "absolute",
- ]);
- });
- });
-});
diff --git a/cypress/e2e/2-advanced-examples/files.cy.js b/cypress/e2e/2-advanced-examples/files.cy.js
deleted file mode 100644
index d161b309..00000000
--- a/cypress/e2e/2-advanced-examples/files.cy.js
+++ /dev/null
@@ -1,87 +0,0 @@
-///
-
-/// JSON fixture file can be loaded directly using
-// the built-in JavaScript bundler
-const requiredExample = require("../../fixtures/example");
-
-context("Files", () => {
- beforeEach(() => {
- cy.visit("https://example.cypress.io/commands/files");
-
- // load example.json fixture file and store
- // in the test context object
- cy.fixture("example.json").as("example");
- });
-
- it("cy.fixture() - load a fixture", () => {
- // https://on.cypress.io/fixture
-
- // Instead of writing a response inline you can
- // use a fixture file's content.
-
- // when application makes an Ajax request matching "GET **/comments/*"
- // Cypress will intercept it and reply with the object in `example.json` fixture
- cy.intercept("GET", "**/comments/*", { fixture: "example.json" }).as(
- "getComment",
- );
-
- // we have code that gets a comment when
- // the button is clicked in scripts.js
- cy.get(".fixture-btn").click();
-
- cy.wait("@getComment")
- .its("response.body")
- .should("have.property", "name")
- .and("include", "Using fixtures to represent data");
- });
-
- it("cy.fixture() or require - load a fixture", function () {
- // we are inside the "function () { ... }"
- // callback and can use test context object "this"
- // "this.example" was loaded in "beforeEach" function callback
- expect(this.example, "fixture in the test context").to.deep.equal(
- requiredExample,
- );
-
- // or use "cy.wrap" and "should('deep.equal', ...)" assertion
- cy.wrap(this.example).should("deep.equal", requiredExample);
- });
-
- it("cy.readFile() - read file contents", () => {
- // https://on.cypress.io/readfile
-
- // You can read a file and yield its contents
- // The filePath is relative to your project's root.
- cy.readFile(Cypress.config("configFile")).then((config) => {
- expect(config).to.be.an("string");
- });
- });
-
- it("cy.writeFile() - write to a file", () => {
- // https://on.cypress.io/writefile
-
- // You can write to a file
-
- // Use a response from a request to automatically
- // generate a fixture file for use later
- cy.request("https://jsonplaceholder.cypress.io/users").then((response) => {
- cy.writeFile("cypress/fixtures/users.json", response.body);
- });
-
- cy.fixture("users").should((users) => {
- expect(users[0].name).to.exist;
- });
-
- // JavaScript arrays and objects are stringified
- // and formatted into text.
- cy.writeFile("cypress/fixtures/profile.json", {
- id: 8739,
- name: "Jane",
- email: "jane@example.com",
- });
-
- cy.fixture("profile").should((profile) => {
- expect(profile.name).to.eq("Jane");
- });
- });
-});
diff --git a/cypress/e2e/2-advanced-examples/location.cy.js b/cypress/e2e/2-advanced-examples/location.cy.js
deleted file mode 100644
index 6f797f14..00000000
--- a/cypress/e2e/2-advanced-examples/location.cy.js
+++ /dev/null
@@ -1,34 +0,0 @@
-///
-
-context("Location", () => {
- beforeEach(() => {
- cy.visit("https://example.cypress.io/commands/location");
- });
-
- it("cy.hash() - get the current URL hash", () => {
- // https://on.cypress.io/hash
- cy.hash().should("be.empty");
- });
-
- it("cy.location() - get window.location", () => {
- // https://on.cypress.io/location
- cy.location().should((location) => {
- expect(location.hash).to.be.empty;
- expect(location.href).to.eq(
- "https://example.cypress.io/commands/location",
- );
- expect(location.host).to.eq("example.cypress.io");
- expect(location.hostname).to.eq("example.cypress.io");
- expect(location.origin).to.eq("https://example.cypress.io");
- expect(location.pathname).to.eq("/commands/location");
- expect(location.port).to.eq("");
- expect(location.protocol).to.eq("https:");
- expect(location.search).to.be.empty;
- });
- });
-
- it("cy.url() - get the current URL", () => {
- // https://on.cypress.io/url
- cy.url().should("eq", "https://example.cypress.io/commands/location");
- });
-});
diff --git a/cypress/e2e/2-advanced-examples/misc.cy.js b/cypress/e2e/2-advanced-examples/misc.cy.js
deleted file mode 100644
index fc6df9aa..00000000
--- a/cypress/e2e/2-advanced-examples/misc.cy.js
+++ /dev/null
@@ -1,106 +0,0 @@
-///
-
-context("Misc", () => {
- beforeEach(() => {
- cy.visit("https://example.cypress.io/commands/misc");
- });
-
- it(".end() - end the command chain", () => {
- // https://on.cypress.io/end
-
- // cy.end is useful when you want to end a chain of commands
- // and force Cypress to re-query from the root element
- cy.get(".misc-table").within(() => {
- // ends the current chain and yields null
- cy.contains("Cheryl").click().end();
-
- // queries the entire table again
- cy.contains("Charles").click();
- });
- });
-
- it("cy.exec() - execute a system command", () => {
- // execute a system command.
- // so you can take actions necessary for
- // your test outside the scope of Cypress.
- // https://on.cypress.io/exec
-
- // we can use Cypress.platform string to
- // select appropriate command
- // https://on.cypress/io/platform
- cy.log(`Platform ${Cypress.platform} architecture ${Cypress.arch}`);
-
- // on CircleCI Windows build machines we have a failure to run bash shell
- // https://github.com/cypress-io/cypress/issues/5169
- // so skip some of the tests by passing flag "--env circle=true"
- const isCircleOnWindows =
- Cypress.platform === "win32" && Cypress.env("circle");
-
- if (isCircleOnWindows) {
- cy.log("Skipping test on CircleCI");
-
- return;
- }
-
- // cy.exec problem on Shippable CI
- // https://github.com/cypress-io/cypress/issues/6718
- const isShippable =
- Cypress.platform === "linux" && Cypress.env("shippable");
-
- if (isShippable) {
- cy.log("Skipping test on ShippableCI");
-
- return;
- }
-
- cy.exec("echo Jane Lane").its("stdout").should("contain", "Jane Lane");
-
- if (Cypress.platform === "win32") {
- cy.exec(`print ${Cypress.config("configFile")}`)
- .its("stderr")
- .should("be.empty");
- } else {
- cy.exec(`cat ${Cypress.config("configFile")}`)
- .its("stderr")
- .should("be.empty");
-
- cy.exec("pwd").its("code").should("eq", 0);
- }
- });
-
- it("cy.focused() - get the DOM element that has focus", () => {
- // https://on.cypress.io/focused
- cy.get(".misc-form").find("#name").click();
- cy.focused().should("have.id", "name");
-
- cy.get(".misc-form").find("#description").click();
- cy.focused().should("have.id", "description");
- });
-
- context("Cypress.Screenshot", function () {
- it("cy.screenshot() - take a screenshot", () => {
- // https://on.cypress.io/screenshot
- cy.screenshot("my-image");
- });
-
- it("Cypress.Screenshot.defaults() - change default config of screenshots", function () {
- Cypress.Screenshot.defaults({
- blackout: [".foo"],
- capture: "viewport",
- clip: { x: 0, y: 0, width: 200, height: 200 },
- scale: false,
- disableTimersAndAnimations: true,
- screenshotOnRunFailure: true,
- onBeforeScreenshot() {},
- onAfterScreenshot() {},
- });
- });
- });
-
- it("cy.wrap() - wrap an object", () => {
- // https://on.cypress.io/wrap
- cy.wrap({ foo: "bar" })
- .should("have.property", "foo")
- .and("include", "bar");
- });
-});
diff --git a/cypress/e2e/2-advanced-examples/navigation.cy.js b/cypress/e2e/2-advanced-examples/navigation.cy.js
deleted file mode 100644
index 2bdae554..00000000
--- a/cypress/e2e/2-advanced-examples/navigation.cy.js
+++ /dev/null
@@ -1,56 +0,0 @@
-///
-
-context("Navigation", () => {
- beforeEach(() => {
- cy.visit("https://example.cypress.io");
- cy.get(".navbar-nav").contains("Commands").click();
- cy.get(".dropdown-menu").contains("Navigation").click();
- });
-
- it("cy.go() - go back or forward in the browser's history", () => {
- // https://on.cypress.io/go
-
- cy.location("pathname").should("include", "navigation");
-
- cy.go("back");
- cy.location("pathname").should("not.include", "navigation");
-
- cy.go("forward");
- cy.location("pathname").should("include", "navigation");
-
- // clicking back
- cy.go(-1);
- cy.location("pathname").should("not.include", "navigation");
-
- // clicking forward
- cy.go(1);
- cy.location("pathname").should("include", "navigation");
- });
-
- it("cy.reload() - reload the page", () => {
- // https://on.cypress.io/reload
- cy.reload();
-
- // reload the page without using the cache
- cy.reload(true);
- });
-
- it("cy.visit() - visit a remote url", () => {
- // https://on.cypress.io/visit
-
- // Visit any sub-domain of your current domain
-
- // Pass options to the visit
- cy.visit("https://example.cypress.io/commands/navigation", {
- timeout: 50000, // increase total time for the visit to resolve
- onBeforeLoad(contentWindow) {
- // contentWindow is the remote page's window object
- expect(typeof contentWindow === "object").to.be.true;
- },
- onLoad(contentWindow) {
- // contentWindow is the remote page's window object
- expect(typeof contentWindow === "object").to.be.true;
- },
- });
- });
-});
diff --git a/cypress/e2e/2-advanced-examples/network_requests.cy.js b/cypress/e2e/2-advanced-examples/network_requests.cy.js
deleted file mode 100644
index 0d49015f..00000000
--- a/cypress/e2e/2-advanced-examples/network_requests.cy.js
+++ /dev/null
@@ -1,184 +0,0 @@
-///
-
-context("Network Requests", () => {
- beforeEach(() => {
- cy.visit("https://example.cypress.io/commands/network-requests");
- });
-
- // Manage HTTP requests in your app
-
- it("cy.request() - make an XHR request", () => {
- // https://on.cypress.io/request
- cy.request("https://jsonplaceholder.cypress.io/comments").should(
- (response) => {
- expect(response.status).to.eq(200);
- // the server sometimes gets an extra comment posted from another machine
- // which gets returned as 1 extra object
- expect(response.body)
- .to.have.property("length")
- .and.be.oneOf([500, 501]);
- expect(response).to.have.property("headers");
- expect(response).to.have.property("duration");
- },
- );
- });
-
- it("cy.request() - verify response using BDD syntax", () => {
- cy.request("https://jsonplaceholder.cypress.io/comments").then(
- (response) => {
- // https://on.cypress.io/assertions
- expect(response).property("status").to.equal(200);
- expect(response)
- .property("body")
- .to.have.property("length")
- .and.be.oneOf([500, 501]);
- expect(response).to.include.keys("headers", "duration");
- },
- );
- });
-
- it("cy.request() with query parameters", () => {
- // will execute request
- // https://jsonplaceholder.cypress.io/comments?postId=1&id=3
- cy.request({
- url: "https://jsonplaceholder.cypress.io/comments",
- qs: {
- postId: 1,
- id: 3,
- },
- })
- .its("body")
- .should("be.an", "array")
- .and("have.length", 1)
- .its("0") // yields first element of the array
- .should("contain", {
- postId: 1,
- id: 3,
- });
- });
-
- it("cy.request() - pass result to the second request", () => {
- // first, let's find out the userId of the first user we have
- cy.request("https://jsonplaceholder.cypress.io/users?_limit=1")
- .its("body") // yields the response object
- .its("0") // yields the first element of the returned list
- // the above two commands its('body').its('0')
- // can be written as its('body.0')
- // if you do not care about TypeScript checks
- .then((user) => {
- expect(user).property("id").to.be.a("number");
- // make a new post on behalf of the user
- cy.request("POST", "https://jsonplaceholder.cypress.io/posts", {
- userId: user.id,
- title: "Cypress Test Runner",
- body: "Fast, easy and reliable testing for anything that runs in a browser.",
- });
- })
- // note that the value here is the returned value of the 2nd request
- // which is the new post object
- .then((response) => {
- expect(response).property("status").to.equal(201); // new entity created
- expect(response).property("body").to.contain({
- title: "Cypress Test Runner",
- });
-
- // we don't know the exact post id - only that it will be > 100
- // since JSONPlaceholder has built-in 100 posts
- expect(response.body)
- .property("id")
- .to.be.a("number")
- .and.to.be.gt(100);
-
- // we don't know the user id here - since it was in above closure
- // so in this test just confirm that the property is there
- expect(response.body).property("userId").to.be.a("number");
- });
- });
-
- it("cy.request() - save response in the shared test context", () => {
- // https://on.cypress.io/variables-and-aliases
- cy.request("https://jsonplaceholder.cypress.io/users?_limit=1")
- .its("body")
- .its("0") // yields the first element of the returned list
- .as("user") // saves the object in the test context
- .then(function () {
- // NOTE đŸ‘€
- // By the time this callback runs the "as('user')" command
- // has saved the user object in the test context.
- // To access the test context we need to use
- // the "function () { ... }" callback form,
- // otherwise "this" points at a wrong or undefined object!
- cy.request("POST", "https://jsonplaceholder.cypress.io/posts", {
- userId: this.user.id,
- title: "Cypress Test Runner",
- body: "Fast, easy and reliable testing for anything that runs in a browser.",
- })
- .its("body")
- .as("post"); // save the new post from the response
- })
- .then(function () {
- // When this callback runs, both "cy.request" API commands have finished
- // and the test context has "user" and "post" objects set.
- // Let's verify them.
- expect(this.post, "post has the right user id")
- .property("userId")
- .to.equal(this.user.id);
- });
- });
-
- it("cy.intercept() - route responses to matching requests", () => {
- // https://on.cypress.io/intercept
-
- let message = "whoa, this comment does not exist";
-
- // Listen to GET to comments/1
- cy.intercept("GET", "**/comments/*").as("getComment");
-
- // we have code that gets a comment when
- // the button is clicked in scripts.js
- cy.get(".network-btn").click();
-
- // https://on.cypress.io/wait
- cy.wait("@getComment")
- .its("response.statusCode")
- .should("be.oneOf", [200, 304]);
-
- // Listen to POST to comments
- cy.intercept("POST", "**/comments").as("postComment");
-
- // we have code that posts a comment when
- // the button is clicked in scripts.js
- cy.get(".network-post").click();
- cy.wait("@postComment").should(({ request, response }) => {
- expect(request.body).to.include("email");
- expect(request.headers).to.have.property("content-type");
- expect(response && response.body).to.have.property(
- "name",
- "Using POST in cy.intercept()",
- );
- });
-
- // Stub a response to PUT comments/ ****
- cy.intercept(
- {
- method: "PUT",
- url: "**/comments/*",
- },
- {
- statusCode: 404,
- body: { error: message },
- headers: { "access-control-allow-origin": "*" },
- delayMs: 500,
- },
- ).as("putComment");
-
- // we have code that puts a comment when
- // the button is clicked in scripts.js
- cy.get(".network-put").click();
-
- cy.wait("@putComment");
-
- // our 404 statusCode logic in scripts.js executed
- cy.get(".network-put-comment").should("contain", message);
- });
-});
diff --git a/cypress/e2e/2-advanced-examples/querying.cy.js b/cypress/e2e/2-advanced-examples/querying.cy.js
deleted file mode 100644
index 3bdef3e8..00000000
--- a/cypress/e2e/2-advanced-examples/querying.cy.js
+++ /dev/null
@@ -1,106 +0,0 @@
-///
-
-context("Querying", () => {
- beforeEach(() => {
- cy.visit("https://example.cypress.io/commands/querying");
- });
-
- // The most commonly used query is 'cy.get()', you can
- // think of this like the '$' in jQuery
-
- it("cy.get() - query DOM elements", () => {
- // https://on.cypress.io/get
-
- cy.get("#query-btn").should("contain", "Button");
-
- cy.get(".query-btn").should("contain", "Button");
-
- cy.get("#querying .well>button:first").should("contain", "Button");
- // ↲
- // Use CSS selectors just like jQuery
-
- cy.get('[data-test-id="test-example"]').should("have.class", "example");
-
- // 'cy.get()' yields jQuery object, you can get its attribute
- // by invoking `.attr()` method
- cy.get('[data-test-id="test-example"]')
- .invoke("attr", "data-test-id")
- .should("equal", "test-example");
-
- // or you can get element's CSS property
- cy.get('[data-test-id="test-example"]')
- .invoke("css", "position")
- .should("equal", "static");
-
- // or use assertions directly during 'cy.get()'
- // https://on.cypress.io/assertions
- cy.get('[data-test-id="test-example"]')
- .should("have.attr", "data-test-id", "test-example")
- .and("have.css", "position", "static");
- });
-
- it("cy.contains() - query DOM elements with matching content", () => {
- // https://on.cypress.io/contains
- cy.get(".query-list").contains("bananas").should("have.class", "third");
-
- // we can pass a regexp to `.contains()`
- cy.get(".query-list").contains(/^b\w+/).should("have.class", "third");
-
- cy.get(".query-list").contains("apples").should("have.class", "first");
-
- // passing a selector to contains will
- // yield the selector containing the text
- cy.get("#querying")
- .contains("ul", "oranges")
- .should("have.class", "query-list");
-
- cy.get(".query-button").contains("Save Form").should("have.class", "btn");
- });
-
- it(".within() - query DOM elements within a specific element", () => {
- // https://on.cypress.io/within
- cy.get(".query-form").within(() => {
- cy.get("input:first").should("have.attr", "placeholder", "Email");
- cy.get("input:last").should("have.attr", "placeholder", "Password");
- });
- });
-
- it("cy.root() - query the root DOM element", () => {
- // https://on.cypress.io/root
-
- // By default, root is the document
- cy.root().should("match", "html");
-
- cy.get(".query-ul").within(() => {
- // In this within, the root is now the ul DOM element
- cy.root().should("have.class", "query-ul");
- });
- });
-
- it("best practices - selecting elements", () => {
- // https://on.cypress.io/best-practices#Selecting-Elements
- cy.get("[data-cy=best-practices-selecting-elements]").within(() => {
- // Worst - too generic, no context
- cy.get("button").click();
-
- // Bad. Coupled to styling. Highly subject to change.
- cy.get(".btn.btn-large").click();
-
- // Average. Coupled to the `name` attribute which has HTML semantics.
- cy.get("[name=submission]").click();
-
- // Better. But still coupled to styling or JS event listeners.
- cy.get("#main").click();
-
- // Slightly better. Uses an ID but also ensures the element
- // has an ARIA role attribute
- cy.get("#main[role=button]").click();
-
- // Much better. But still coupled to text content that may change.
- cy.contains("Submit").click();
-
- // Best. Insulated from all changes.
- cy.get("[data-cy=submit]").click();
- });
- });
-});
diff --git a/cypress/e2e/2-advanced-examples/spies_stubs_clocks.cy.js b/cypress/e2e/2-advanced-examples/spies_stubs_clocks.cy.js
deleted file mode 100644
index c4080a9b..00000000
--- a/cypress/e2e/2-advanced-examples/spies_stubs_clocks.cy.js
+++ /dev/null
@@ -1,213 +0,0 @@
-///
-
-context("Spies, Stubs, and Clock", () => {
- it("cy.spy() - wrap a method in a spy", () => {
- // https://on.cypress.io/spy
- cy.visit("https://example.cypress.io/commands/spies-stubs-clocks");
-
- const obj = {
- foo() {},
- };
-
- const spy = cy.spy(obj, "foo").as("anyArgs");
-
- obj.foo();
-
- expect(spy).to.be.called;
- });
-
- it("cy.spy() retries until assertions pass", () => {
- cy.visit("https://example.cypress.io/commands/spies-stubs-clocks");
-
- const obj = {
- /**
- * Prints the argument passed
- * @param x {any}
- */
- foo(x) {
- console.log("obj.foo called with", x);
- },
- };
-
- cy.spy(obj, "foo").as("foo");
-
- setTimeout(() => {
- obj.foo("first");
- }, 500);
-
- setTimeout(() => {
- obj.foo("second");
- }, 2500);
-
- cy.get("@foo").should("have.been.calledTwice");
- });
-
- it("cy.stub() - create a stub and/or replace a function with stub", () => {
- // https://on.cypress.io/stub
- cy.visit("https://example.cypress.io/commands/spies-stubs-clocks");
-
- const obj = {
- /**
- * prints both arguments to the console
- * @param a {string}
- * @param b {string}
- */
- foo(a, b) {
- console.log("a", a, "b", b);
- },
- };
-
- const stub = cy.stub(obj, "foo").as("foo");
-
- obj.foo("foo", "bar");
-
- expect(stub).to.be.called;
- });
-
- it("cy.clock() - control time in the browser", () => {
- // https://on.cypress.io/clock
-
- // create the date in UTC so its always the same
- // no matter what local timezone the browser is running in
- const now = new Date(Date.UTC(2017, 2, 14)).getTime();
-
- cy.clock(now);
- cy.visit("https://example.cypress.io/commands/spies-stubs-clocks");
- cy.get("#clock-div").click().should("have.text", "1489449600");
- });
-
- it("cy.tick() - move time in the browser", () => {
- // https://on.cypress.io/tick
-
- // create the date in UTC so its always the same
- // no matter what local timezone the browser is running in
- const now = new Date(Date.UTC(2017, 2, 14)).getTime();
-
- cy.clock(now);
- cy.visit("https://example.cypress.io/commands/spies-stubs-clocks");
- cy.get("#tick-div").click().should("have.text", "1489449600");
-
- cy.tick(10000); // 10 seconds passed
- cy.get("#tick-div").click().should("have.text", "1489449610");
- });
-
- it("cy.stub() matches depending on arguments", () => {
- // see all possible matchers at
- // https://sinonjs.org/releases/latest/matchers/
- const greeter = {
- /**
- * Greets a person
- * @param {string} name
- */
- greet(name) {
- return `Hello, ${name}!`;
- },
- };
-
- cy.stub(greeter, "greet")
- .callThrough() // if you want non-matched calls to call the real method
- .withArgs(Cypress.sinon.match.string)
- .returns("Hi")
- .withArgs(Cypress.sinon.match.number)
- .throws(new Error("Invalid name"));
-
- expect(greeter.greet("World")).to.equal("Hi");
- expect(() => greeter.greet(42)).to.throw("Invalid name");
- expect(greeter.greet).to.have.been.calledTwice;
-
- // non-matched calls goes the actual method
- expect(greeter.greet()).to.equal("Hello, undefined!");
- });
-
- it("matches call arguments using Sinon matchers", () => {
- // see all possible matchers at
- // https://sinonjs.org/releases/latest/matchers/
- const calculator = {
- /**
- * returns the sum of two arguments
- * @param a {number}
- * @param b {number}
- */
- add(a, b) {
- return a + b;
- },
- };
-
- const spy = cy.spy(calculator, "add").as("add");
-
- expect(calculator.add(2, 3)).to.equal(5);
-
- // if we want to assert the exact values used during the call
- expect(spy).to.be.calledWith(2, 3);
-
- // let's confirm "add" method was called with two numbers
- expect(spy).to.be.calledWith(
- Cypress.sinon.match.number,
- Cypress.sinon.match.number,
- );
-
- // alternatively, provide the value to match
- expect(spy).to.be.calledWith(
- Cypress.sinon.match(2),
- Cypress.sinon.match(3),
- );
-
- // match any value
- expect(spy).to.be.calledWith(Cypress.sinon.match.any, 3);
-
- // match any value from a list
- expect(spy).to.be.calledWith(Cypress.sinon.match.in([1, 2, 3]), 3);
-
- /**
- * Returns true if the given number is even
- * @param {number} x
- */
- const isEven = (x) => x % 2 === 0;
-
- // expect the value to pass a custom predicate function
- // the second argument to "sinon.match(predicate, message)" is
- // shown if the predicate does not pass and assertion fails
- expect(spy).to.be.calledWith(Cypress.sinon.match(isEven, "isEven"), 3);
-
- /**
- * Returns a function that checks if a given number is larger than the limit
- * @param {number} limit
- * @returns {(x: number) => boolean}
- */
- const isGreaterThan = (limit) => (x) => x > limit;
-
- /**
- * Returns a function that checks if a given number is less than the limit
- * @param {number} limit
- * @returns {(x: number) => boolean}
- */
- const isLessThan = (limit) => (x) => x < limit;
-
- // you can combine several matchers using "and", "or"
- expect(spy).to.be.calledWith(
- Cypress.sinon.match.number,
- Cypress.sinon
- .match(isGreaterThan(2), "> 2")
- .and(Cypress.sinon.match(isLessThan(4), "< 4")),
- );
-
- expect(spy).to.be.calledWith(
- Cypress.sinon.match.number,
- Cypress.sinon
- .match(isGreaterThan(200), "> 200")
- .or(Cypress.sinon.match(3)),
- );
-
- // matchers can be used from BDD assertions
- cy.get("@add").should(
- "have.been.calledWith",
- Cypress.sinon.match.number,
- Cypress.sinon.match(3),
- );
-
- // you can alias matchers for shorter test code
- const { match: M } = Cypress.sinon;
-
- cy.get("@add").should("have.been.calledWith", M.number, M(3));
- });
-});
diff --git a/cypress/e2e/2-advanced-examples/storage.cy.js b/cypress/e2e/2-advanced-examples/storage.cy.js
deleted file mode 100644
index f9277940..00000000
--- a/cypress/e2e/2-advanced-examples/storage.cy.js
+++ /dev/null
@@ -1,116 +0,0 @@
-///
-
-context("Local Storage / Session Storage", () => {
- beforeEach(() => {
- cy.visit("https://example.cypress.io/commands/storage");
- });
- // Although localStorage is automatically cleared
- // in between tests to maintain a clean state
- // sometimes we need to clear localStorage manually
-
- it("cy.clearLocalStorage() - clear all data in localStorage for the current origin", () => {
- // https://on.cypress.io/clearlocalstorage
- cy.get(".ls-btn")
- .click()
- .should(() => {
- expect(localStorage.getItem("prop1")).to.eq("red");
- expect(localStorage.getItem("prop2")).to.eq("blue");
- expect(localStorage.getItem("prop3")).to.eq("magenta");
- });
-
- // clearLocalStorage() yields the localStorage object
- cy.clearLocalStorage().should((ls) => {
- expect(ls.getItem("prop1")).to.be.null;
- expect(ls.getItem("prop2")).to.be.null;
- expect(ls.getItem("prop3")).to.be.null;
- });
-
- cy.get(".ls-btn")
- .click()
- .should(() => {
- expect(localStorage.getItem("prop1")).to.eq("red");
- expect(localStorage.getItem("prop2")).to.eq("blue");
- expect(localStorage.getItem("prop3")).to.eq("magenta");
- });
-
- // Clear key matching string in localStorage
- cy.clearLocalStorage("prop1").should((ls) => {
- expect(ls.getItem("prop1")).to.be.null;
- expect(ls.getItem("prop2")).to.eq("blue");
- expect(ls.getItem("prop3")).to.eq("magenta");
- });
-
- cy.get(".ls-btn")
- .click()
- .should(() => {
- expect(localStorage.getItem("prop1")).to.eq("red");
- expect(localStorage.getItem("prop2")).to.eq("blue");
- expect(localStorage.getItem("prop3")).to.eq("magenta");
- });
-
- // Clear keys matching regex in localStorage
- cy.clearLocalStorage(/prop1|2/).should((ls) => {
- expect(ls.getItem("prop1")).to.be.null;
- expect(ls.getItem("prop2")).to.be.null;
- expect(ls.getItem("prop3")).to.eq("magenta");
- });
- });
-
- it("cy.getAllLocalStorage() - get all data in localStorage for all origins", () => {
- // https://on.cypress.io/getalllocalstorage
- cy.get(".ls-btn").click();
-
- // getAllLocalStorage() yields a map of origins to localStorage values
- cy.getAllLocalStorage().should((storageMap) => {
- expect(storageMap).to.deep.equal({
- // other origins will also be present if localStorage is set on them
- "https://example.cypress.io": {
- prop1: "red",
- prop2: "blue",
- prop3: "magenta",
- },
- });
- });
- });
-
- it("cy.clearAllLocalStorage() - clear all data in localStorage for all origins", () => {
- // https://on.cypress.io/clearalllocalstorage
- cy.get(".ls-btn").click();
-
- // clearAllLocalStorage() yields null
- cy.clearAllLocalStorage().should(() => {
- expect(sessionStorage.getItem("prop1")).to.be.null;
- expect(sessionStorage.getItem("prop2")).to.be.null;
- expect(sessionStorage.getItem("prop3")).to.be.null;
- });
- });
-
- it("cy.getAllSessionStorage() - get all data in sessionStorage for all origins", () => {
- // https://on.cypress.io/getallsessionstorage
- cy.get(".ls-btn").click();
-
- // getAllSessionStorage() yields a map of origins to sessionStorage values
- cy.getAllSessionStorage().should((storageMap) => {
- expect(storageMap).to.deep.equal({
- // other origins will also be present if sessionStorage is set on them
- "https://example.cypress.io": {
- prop4: "cyan",
- prop5: "yellow",
- prop6: "black",
- },
- });
- });
- });
-
- it("cy.clearAllSessionStorage() - clear all data in sessionStorage for all origins", () => {
- // https://on.cypress.io/clearallsessionstorage
- cy.get(".ls-btn").click();
-
- // clearAllSessionStorage() yields null
- cy.clearAllSessionStorage().should(() => {
- expect(sessionStorage.getItem("prop4")).to.be.null;
- expect(sessionStorage.getItem("prop5")).to.be.null;
- expect(sessionStorage.getItem("prop6")).to.be.null;
- });
- });
-});
diff --git a/cypress/e2e/2-advanced-examples/traversal.cy.js b/cypress/e2e/2-advanced-examples/traversal.cy.js
deleted file mode 100644
index 2ee4b9bf..00000000
--- a/cypress/e2e/2-advanced-examples/traversal.cy.js
+++ /dev/null
@@ -1,116 +0,0 @@
-///
-
-context("Traversal", () => {
- beforeEach(() => {
- cy.visit("https://example.cypress.io/commands/traversal");
- });
-
- it(".children() - get child DOM elements", () => {
- // https://on.cypress.io/children
- cy.get(".traversal-breadcrumb")
- .children(".active")
- .should("contain", "Data");
- });
-
- it(".closest() - get closest ancestor DOM element", () => {
- // https://on.cypress.io/closest
- cy.get(".traversal-badge").closest("ul").should("have.class", "list-group");
- });
-
- it(".eq() - get a DOM element at a specific index", () => {
- // https://on.cypress.io/eq
- cy.get(".traversal-list>li").eq(1).should("contain", "siamese");
- });
-
- it(".filter() - get DOM elements that match the selector", () => {
- // https://on.cypress.io/filter
- cy.get(".traversal-nav>li").filter(".active").should("contain", "About");
- });
-
- it(".find() - get descendant DOM elements of the selector", () => {
- // https://on.cypress.io/find
- cy.get(".traversal-pagination")
- .find("li")
- .find("a")
- .should("have.length", 7);
- });
-
- it(".first() - get first DOM element", () => {
- // https://on.cypress.io/first
- cy.get(".traversal-table td").first().should("contain", "1");
- });
-
- it(".last() - get last DOM element", () => {
- // https://on.cypress.io/last
- cy.get(".traversal-buttons .btn").last().should("contain", "Submit");
- });
-
- it(".next() - get next sibling DOM element", () => {
- // https://on.cypress.io/next
- cy.get(".traversal-ul")
- .contains("apples")
- .next()
- .should("contain", "oranges");
- });
-
- it(".nextAll() - get all next sibling DOM elements", () => {
- // https://on.cypress.io/nextall
- cy.get(".traversal-next-all")
- .contains("oranges")
- .nextAll()
- .should("have.length", 3);
- });
-
- it(".nextUntil() - get next sibling DOM elements until next el", () => {
- // https://on.cypress.io/nextuntil
- cy.get("#veggies").nextUntil("#nuts").should("have.length", 3);
- });
-
- it(".not() - remove DOM elements from set of DOM elements", () => {
- // https://on.cypress.io/not
- cy.get(".traversal-disabled .btn")
- .not("[disabled]")
- .should("not.contain", "Disabled");
- });
-
- it(".parent() - get parent DOM element from DOM elements", () => {
- // https://on.cypress.io/parent
- cy.get(".traversal-mark").parent().should("contain", "Morbi leo risus");
- });
-
- it(".parents() - get parent DOM elements from DOM elements", () => {
- // https://on.cypress.io/parents
- cy.get(".traversal-cite").parents().should("match", "blockquote");
- });
-
- it(".parentsUntil() - get parent DOM elements from DOM elements until el", () => {
- // https://on.cypress.io/parentsuntil
- cy.get(".clothes-nav")
- .find(".active")
- .parentsUntil(".clothes-nav")
- .should("have.length", 2);
- });
-
- it(".prev() - get previous sibling DOM element", () => {
- // https://on.cypress.io/prev
- cy.get(".birds").find(".active").prev().should("contain", "Lorikeets");
- });
-
- it(".prevAll() - get all previous sibling DOM elements", () => {
- // https://on.cypress.io/prevall
- cy.get(".fruits-list").find(".third").prevAll().should("have.length", 2);
- });
-
- it(".prevUntil() - get all previous sibling DOM elements until el", () => {
- // https://on.cypress.io/prevuntil
- cy.get(".foods-list")
- .find("#nuts")
- .prevUntil("#veggies")
- .should("have.length", 3);
- });
-
- it(".siblings() - get all sibling DOM elements", () => {
- // https://on.cypress.io/siblings
- cy.get(".traversal-pills .active").siblings().should("have.length", 2);
- });
-});
diff --git a/cypress/e2e/2-advanced-examples/utilities.cy.js b/cypress/e2e/2-advanced-examples/utilities.cy.js
deleted file mode 100644
index aa271b62..00000000
--- a/cypress/e2e/2-advanced-examples/utilities.cy.js
+++ /dev/null
@@ -1,109 +0,0 @@
-///
-
-context("Utilities", () => {
- beforeEach(() => {
- cy.visit("https://example.cypress.io/utilities");
- });
-
- it("Cypress._ - call a lodash method", () => {
- // https://on.cypress.io/_
- cy.request("https://jsonplaceholder.cypress.io/users").then((response) => {
- let ids = Cypress._.chain(response.body).map("id").take(3).value();
-
- expect(ids).to.deep.eq([1, 2, 3]);
- });
- });
-
- it("Cypress.$ - call a jQuery method", () => {
- // https://on.cypress.io/$
- let $li = Cypress.$(".utility-jquery li:first");
-
- cy.wrap($li)
- .should("not.have.class", "active")
- .click()
- .should("have.class", "active");
- });
-
- it("Cypress.Blob - blob utilities and base64 string conversion", () => {
- // https://on.cypress.io/blob
- cy.get(".utility-blob").then(($div) => {
- // https://github.com/nolanlawson/blob-util#imgSrcToDataURL
- // get the dataUrl string for the javascript-logo
- return Cypress.Blob.imgSrcToDataURL(
- "https://example.cypress.io/assets/img/javascript-logo.png",
- undefined,
- "anonymous",
- ).then((dataUrl) => {
- // create an element and set its src to the dataUrl
- let img = Cypress.$("", { src: dataUrl });
-
- // need to explicitly return cy here since we are initially returning
- // the Cypress.Blob.imgSrcToDataURL promise to our test
- // append the image
- $div.append(img);
-
- cy.get(".utility-blob img").click().should("have.attr", "src", dataUrl);
- });
- });
- });
-
- it("Cypress.minimatch - test out glob patterns against strings", () => {
- // https://on.cypress.io/minimatch
- let matching = Cypress.minimatch("/users/1/comments", "/users/*/comments", {
- matchBase: true,
- });
-
- expect(matching, "matching wildcard").to.be.true;
-
- matching = Cypress.minimatch("/users/1/comments/2", "/users/*/comments", {
- matchBase: true,
- });
-
- expect(matching, "comments").to.be.false;
-
- // ** matches against all downstream path segments
- matching = Cypress.minimatch("/foo/bar/baz/123/quux?a=b&c=2", "/foo/**", {
- matchBase: true,
- });
-
- expect(matching, "comments").to.be.true;
-
- // whereas * matches only the next path segment
-
- matching = Cypress.minimatch("/foo/bar/baz/123/quux?a=b&c=2", "/foo/*", {
- matchBase: false,
- });
-
- expect(matching, "comments").to.be.false;
- });
-
- it("Cypress.Promise - instantiate a bluebird promise", () => {
- // https://on.cypress.io/promise
- let waited = false;
-
- /**
- * @return Bluebird
- */
- function waitOneSecond() {
- // return a promise that resolves after 1 second
- return new Cypress.Promise((resolve, reject) => {
- setTimeout(() => {
- // set waited to true
- waited = true;
-
- // resolve with 'foo' string
- resolve("foo");
- }, 1000);
- });
- }
-
- cy.then(() => {
- // return a promise to cy.then() that
- // is awaited until it resolves
- return waitOneSecond().then((str) => {
- expect(str).to.eq("foo");
- expect(waited).to.be.true;
- });
- });
- });
-});
diff --git a/cypress/e2e/2-advanced-examples/viewport.cy.js b/cypress/e2e/2-advanced-examples/viewport.cy.js
deleted file mode 100644
index 2d0644ab..00000000
--- a/cypress/e2e/2-advanced-examples/viewport.cy.js
+++ /dev/null
@@ -1,59 +0,0 @@
-///
-
-context("Viewport", () => {
- beforeEach(() => {
- cy.visit("https://example.cypress.io/commands/viewport");
- });
-
- it("cy.viewport() - set the viewport size and dimension", () => {
- // https://on.cypress.io/viewport
-
- cy.get("#navbar").should("be.visible");
- cy.viewport(320, 480);
-
- // the navbar should have collapse since our screen is smaller
- cy.get("#navbar").should("not.be.visible");
- cy.get(".navbar-toggle").should("be.visible").click();
- cy.get(".nav").find("a").should("be.visible");
-
- // lets see what our app looks like on a super large screen
- cy.viewport(2999, 2999);
-
- // cy.viewport() accepts a set of preset sizes
- // to easily set the screen to a device's width and height
-
- // We added a cy.wait() between each viewport change so you can see
- // the change otherwise it is a little too fast to see :)
-
- cy.viewport("macbook-15");
- cy.wait(200);
- cy.viewport("macbook-13");
- cy.wait(200);
- cy.viewport("macbook-11");
- cy.wait(200);
- cy.viewport("ipad-2");
- cy.wait(200);
- cy.viewport("ipad-mini");
- cy.wait(200);
- cy.viewport("iphone-6+");
- cy.wait(200);
- cy.viewport("iphone-6");
- cy.wait(200);
- cy.viewport("iphone-5");
- cy.wait(200);
- cy.viewport("iphone-4");
- cy.wait(200);
- cy.viewport("iphone-3");
- cy.wait(200);
-
- // cy.viewport() accepts an orientation for all presets
- // the default orientation is 'portrait'
- cy.viewport("ipad-2", "portrait");
- cy.wait(200);
- cy.viewport("iphone-4", "landscape");
- cy.wait(200);
-
- // The viewport will be reset back to the default dimensions
- // in between tests (the default can be set in cypress.config.{js|ts})
- });
-});
diff --git a/cypress/e2e/2-advanced-examples/waiting.cy.js b/cypress/e2e/2-advanced-examples/waiting.cy.js
deleted file mode 100644
index 7e9feeb0..00000000
--- a/cypress/e2e/2-advanced-examples/waiting.cy.js
+++ /dev/null
@@ -1,33 +0,0 @@
-///
-
-context("Waiting", () => {
- beforeEach(() => {
- cy.visit("https://example.cypress.io/commands/waiting");
- });
- // BE CAREFUL of adding unnecessary wait times.
- // https://on.cypress.io/best-practices#Unnecessary-Waiting
-
- // https://on.cypress.io/wait
- it("cy.wait() - wait for a specific amount of time", () => {
- cy.get(".wait-input1").type("Wait 1000ms after typing");
- cy.wait(1000);
- cy.get(".wait-input2").type("Wait 1000ms after typing");
- cy.wait(1000);
- cy.get(".wait-input3").type("Wait 1000ms after typing");
- cy.wait(1000);
- });
-
- it("cy.wait() - wait for a specific route", () => {
- // Listen to GET to comments/1
- cy.intercept("GET", "**/comments/*").as("getComment");
-
- // we have code that gets a comment when
- // the button is clicked in scripts.js
- cy.get(".network-btn").click();
-
- // wait for GET comments/1
- cy.wait("@getComment")
- .its("response.statusCode")
- .should("be.oneOf", [200, 304]);
- });
-});
diff --git a/cypress/e2e/2-advanced-examples/window.cy.js b/cypress/e2e/2-advanced-examples/window.cy.js
deleted file mode 100644
index 9740ba04..00000000
--- a/cypress/e2e/2-advanced-examples/window.cy.js
+++ /dev/null
@@ -1,22 +0,0 @@
-///
-
-context("Window", () => {
- beforeEach(() => {
- cy.visit("https://example.cypress.io/commands/window");
- });
-
- it("cy.window() - get the global window object", () => {
- // https://on.cypress.io/window
- cy.window().should("have.property", "top");
- });
-
- it("cy.document() - get the document object", () => {
- // https://on.cypress.io/document
- cy.document().should("have.property", "charset").and("eq", "UTF-8");
- });
-
- it("cy.title() - get the title", () => {
- // https://on.cypress.io/title
- cy.title().should("include", "Kitchen Sink");
- });
-});
diff --git a/cypress/fixtures/profile.json b/cypress/fixtures/profile.json
new file mode 100644
index 00000000..a95e88f9
--- /dev/null
+++ b/cypress/fixtures/profile.json
@@ -0,0 +1,5 @@
+{
+ "id": 8739,
+ "name": "Jane",
+ "email": "jane@example.com"
+}
diff --git a/cypress/fixtures/users.json b/cypress/fixtures/users.json
new file mode 100644
index 00000000..82a0056b
--- /dev/null
+++ b/cypress/fixtures/users.json
@@ -0,0 +1,232 @@
+[
+ {
+ "id": 1,
+ "name": "Leanne Graham",
+ "username": "Bret",
+ "email": "Sincere@april.biz",
+ "address": {
+ "street": "Kulas Light",
+ "suite": "Apt. 556",
+ "city": "Gwenborough",
+ "zipcode": "92998-3874",
+ "geo": {
+ "lat": "-37.3159",
+ "lng": "81.1496"
+ }
+ },
+ "phone": "1-770-736-8031 x56442",
+ "website": "hildegard.org",
+ "company": {
+ "name": "Romaguera-Crona",
+ "catchPhrase": "Multi-layered client-server neural-net",
+ "bs": "harness real-time e-markets"
+ }
+ },
+ {
+ "id": 2,
+ "name": "Ervin Howell",
+ "username": "Antonette",
+ "email": "Shanna@melissa.tv",
+ "address": {
+ "street": "Victor Plains",
+ "suite": "Suite 879",
+ "city": "Wisokyburgh",
+ "zipcode": "90566-7771",
+ "geo": {
+ "lat": "-43.9509",
+ "lng": "-34.4618"
+ }
+ },
+ "phone": "010-692-6593 x09125",
+ "website": "anastasia.net",
+ "company": {
+ "name": "Deckow-Crist",
+ "catchPhrase": "Proactive didactic contingency",
+ "bs": "synergize scalable supply-chains"
+ }
+ },
+ {
+ "id": 3,
+ "name": "Clementine Bauch",
+ "username": "Samantha",
+ "email": "Nathan@yesenia.net",
+ "address": {
+ "street": "Douglas Extension",
+ "suite": "Suite 847",
+ "city": "McKenziehaven",
+ "zipcode": "59590-4157",
+ "geo": {
+ "lat": "-68.6102",
+ "lng": "-47.0653"
+ }
+ },
+ "phone": "1-463-123-4447",
+ "website": "ramiro.info",
+ "company": {
+ "name": "Romaguera-Jacobson",
+ "catchPhrase": "Face to face bifurcated interface",
+ "bs": "e-enable strategic applications"
+ }
+ },
+ {
+ "id": 4,
+ "name": "Patricia Lebsack",
+ "username": "Karianne",
+ "email": "Julianne.OConner@kory.org",
+ "address": {
+ "street": "Hoeger Mall",
+ "suite": "Apt. 692",
+ "city": "South Elvis",
+ "zipcode": "53919-4257",
+ "geo": {
+ "lat": "29.4572",
+ "lng": "-164.2990"
+ }
+ },
+ "phone": "493-170-9623 x156",
+ "website": "kale.biz",
+ "company": {
+ "name": "Robel-Corkery",
+ "catchPhrase": "Multi-tiered zero tolerance productivity",
+ "bs": "transition cutting-edge web services"
+ }
+ },
+ {
+ "id": 5,
+ "name": "Chelsey Dietrich",
+ "username": "Kamren",
+ "email": "Lucio_Hettinger@annie.ca",
+ "address": {
+ "street": "Skiles Walks",
+ "suite": "Suite 351",
+ "city": "Roscoeview",
+ "zipcode": "33263",
+ "geo": {
+ "lat": "-31.8129",
+ "lng": "62.5342"
+ }
+ },
+ "phone": "(254)954-1289",
+ "website": "demarco.info",
+ "company": {
+ "name": "Keebler LLC",
+ "catchPhrase": "User-centric fault-tolerant solution",
+ "bs": "revolutionize end-to-end systems"
+ }
+ },
+ {
+ "id": 6,
+ "name": "Mrs. Dennis Schulist",
+ "username": "Leopoldo_Corkery",
+ "email": "Karley_Dach@jasper.info",
+ "address": {
+ "street": "Norberto Crossing",
+ "suite": "Apt. 950",
+ "city": "South Christy",
+ "zipcode": "23505-1337",
+ "geo": {
+ "lat": "-71.4197",
+ "lng": "71.7478"
+ }
+ },
+ "phone": "1-477-935-8478 x6430",
+ "website": "ola.org",
+ "company": {
+ "name": "Considine-Lockman",
+ "catchPhrase": "Synchronised bottom-line interface",
+ "bs": "e-enable innovative applications"
+ }
+ },
+ {
+ "id": 7,
+ "name": "Kurtis Weissnat",
+ "username": "Elwyn.Skiles",
+ "email": "Telly.Hoeger@billy.biz",
+ "address": {
+ "street": "Rex Trail",
+ "suite": "Suite 280",
+ "city": "Howemouth",
+ "zipcode": "58804-1099",
+ "geo": {
+ "lat": "24.8918",
+ "lng": "21.8984"
+ }
+ },
+ "phone": "210.067.6132",
+ "website": "elvis.io",
+ "company": {
+ "name": "Johns Group",
+ "catchPhrase": "Configurable multimedia task-force",
+ "bs": "generate enterprise e-tailers"
+ }
+ },
+ {
+ "id": 8,
+ "name": "Nicholas Runolfsdottir V",
+ "username": "Maxime_Nienow",
+ "email": "Sherwood@rosamond.me",
+ "address": {
+ "street": "Ellsworth Summit",
+ "suite": "Suite 729",
+ "city": "Aliyaview",
+ "zipcode": "45169",
+ "geo": {
+ "lat": "-14.3990",
+ "lng": "-120.7677"
+ }
+ },
+ "phone": "586.493.6943 x140",
+ "website": "jacynthe.com",
+ "company": {
+ "name": "Abernathy Group",
+ "catchPhrase": "Implemented secondary concept",
+ "bs": "e-enable extensible e-tailers"
+ }
+ },
+ {
+ "id": 9,
+ "name": "Glenna Reichert",
+ "username": "Delphine",
+ "email": "Chaim_McDermott@dana.io",
+ "address": {
+ "street": "Dayna Park",
+ "suite": "Suite 449",
+ "city": "Bartholomebury",
+ "zipcode": "76495-3109",
+ "geo": {
+ "lat": "24.6463",
+ "lng": "-168.8889"
+ }
+ },
+ "phone": "(775)976-6794 x41206",
+ "website": "conrad.com",
+ "company": {
+ "name": "Yost and Sons",
+ "catchPhrase": "Switchable contextually-based project",
+ "bs": "aggregate real-time technologies"
+ }
+ },
+ {
+ "id": 10,
+ "name": "Clementina DuBuque",
+ "username": "Moriah.Stanton",
+ "email": "Rey.Padberg@karina.biz",
+ "address": {
+ "street": "Kattie Turnpike",
+ "suite": "Suite 198",
+ "city": "Lebsackbury",
+ "zipcode": "31428-2261",
+ "geo": {
+ "lat": "-38.2386",
+ "lng": "57.2232"
+ }
+ },
+ "phone": "024-648-3804",
+ "website": "ambrose.net",
+ "company": {
+ "name": "Hoeger LLC",
+ "catchPhrase": "Centralized empowering task-force",
+ "bs": "target end-to-end models"
+ }
+ }
+]
diff --git a/cypress/tsconfig.json b/cypress/tsconfig.json
new file mode 100644
index 00000000..13c406e5
--- /dev/null
+++ b/cypress/tsconfig.json
@@ -0,0 +1,8 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "lib": ["es5", "dom"],
+ "types": ["cypress", "node"]
+ },
+ "include": ["../node_modules/cypress", "**/*.ts"]
+}
diff --git a/docker-compose.yml b/docker-compose.yml
deleted file mode 100644
index 4560cd1c..00000000
--- a/docker-compose.yml
+++ /dev/null
@@ -1,44 +0,0 @@
-version: "3.7"
-services:
- app:
- stdin_open: true
- container_name: app
- build:
- dockerfile: Dockerfile.dev
- context: .
- ports:
- - 3000:3000
- - 5555:5555
- depends_on:
- - db
- environment:
- - WATCHPACK_POLLING=true
- volumes:
- - .:/usr/src/app
- - /usr/src/app/node_modules
- db:
- container_name: db
- image: postgres:latest
- hostname: $HOSTNAME
- environment:
- POSTGRES_USER: $POSTGRES_USER
- POSTGRES_PASSWORD: $POSTGRES_PASSWORD
- POSTGRES_DB: $POSTGRES_DB
- PGPORT: 5433
- volumes:
- - postgres-data:/var/lib/postgresql/data
- pgadmin:
- image: dpage/pgadmin4
- container_name: pgadmin
- depends_on:
- - db
- ports:
- - "4000:80"
- environment:
- PGADMIN_DEFAULT_EMAIL: $PGADMIN_EMAIL
- PGADMIN_DEFAULT_PASSWORD: $PGADMIN_PW
- volumes:
- - pgadmin-data:/var/lib/pgadmin
-volumes:
- postgres-data:
- pgadmin-data:
diff --git a/package.json b/package.json
index e0b3948d..bcf7f8e1 100644
--- a/package.json
+++ b/package.json
@@ -3,8 +3,8 @@
"version": "0.1.0",
"private": true,
"scripts": {
- "dev": "prisma generate && next dev",
- "build": "prisma generate && next build",
+ "dev": "next dev",
+ "build": "next build",
"start": "next start",
"lint": "next lint",
"prettier": "prettier . --write",
@@ -14,11 +14,9 @@
},
"dependencies": {
"@heroicons/react": "^2.0.18",
- "@prisma/client": "5.1.1",
"@reduxjs/toolkit": "^1.9.5",
"next": "13.4.12",
- "next-auth": "^4.22.3",
- "prisma": "^5.1.1",
+ "next-themes": "^0.2.1",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-redux": "^8.1.2",
@@ -41,6 +39,7 @@
"eslint-config-prettier": "^8.10.0",
"eslint-import-resolver-typescript": "^3.5.5",
"eslint-plugin-import": "^2.28.0",
+ "eslint-plugin-no-relative-import-paths": "^1.5.2",
"husky": "^8.0.0",
"jest": "^29.6.2",
"jest-environment-jsdom": "^29.6.2",
diff --git a/prisma/migrations/20230807161830_initial_setup/migration.sql b/prisma/migrations/20230807161830_initial_setup/migration.sql
deleted file mode 100644
index 0d627675..00000000
--- a/prisma/migrations/20230807161830_initial_setup/migration.sql
+++ /dev/null
@@ -1,7 +0,0 @@
--- CreateTable
-CREATE TABLE "User" (
- "uuid" UUID NOT NULL,
- "username" VARCHAR(255) NOT NULL,
-
- CONSTRAINT "User_pkey" PRIMARY KEY ("uuid")
-);
diff --git a/prisma/migrations/migration_lock.toml b/prisma/migrations/migration_lock.toml
deleted file mode 100644
index fbffa92c..00000000
--- a/prisma/migrations/migration_lock.toml
+++ /dev/null
@@ -1,3 +0,0 @@
-# Please do not edit this file manually
-# It should be added in your version-control system (i.e. Git)
-provider = "postgresql"
\ No newline at end of file
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
deleted file mode 100644
index 719428f3..00000000
--- a/prisma/schema.prisma
+++ /dev/null
@@ -1,16 +0,0 @@
-// This is your Prisma schema file,
-// learn more about it in the docs: https://pris.ly/d/prisma-schema
-
-generator client {
- provider = "prisma-client-js"
-}
-
-datasource db {
- provider = "postgresql"
- url = env("DATABASE_URL")
-}
-
-model User {
- uuid String @id @default(uuid()) @db.Uuid
- username String @db.VarChar(255)
-}
diff --git a/public/grey_ball.png b/public/grey_ball.png
deleted file mode 100644
index 5f3cd173..00000000
Binary files a/public/grey_ball.png and /dev/null differ
diff --git a/public/avatar.png b/public/img/avatar.png
similarity index 100%
rename from public/avatar.png
rename to public/img/avatar.png
diff --git a/public/chingu_logo.png b/public/img/chingu_logo.png
similarity index 100%
rename from public/chingu_logo.png
rename to public/img/chingu_logo.png
diff --git a/public/img/directory_banner.png b/public/img/directory_banner.png
new file mode 100644
index 00000000..bb8a1eea
Binary files /dev/null and b/public/img/directory_banner.png differ
diff --git a/public/img/ideation_banner.svg b/public/img/ideation_banner.svg
new file mode 100644
index 00000000..7a4d7cb0
--- /dev/null
+++ b/public/img/ideation_banner.svg
@@ -0,0 +1,53 @@
+
diff --git a/public/img/tech_stack_banner.png b/public/img/tech_stack_banner.png
new file mode 100644
index 00000000..8c637cef
Binary files /dev/null and b/public/img/tech_stack_banner.png differ
diff --git a/pull_request_template.md b/pull_request_template.md
new file mode 100644
index 00000000..aa7da788
--- /dev/null
+++ b/pull_request_template.md
@@ -0,0 +1,30 @@
+# Description
+
+Please include a summary of the changes and the related issue. Please also include relevant motivation and context. List any dependencies that are required for this change.
+
+## Issue link
+
+Fixes # (issue)
+
+## Type of change
+
+- [ ] Bug fix (non-breaking change which fixes an issue)
+- [ ] New feature (non-breaking change which adds functionality)
+- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
+- [ ] This change requires a documentation update
+
+# How Has This Been Tested?
+
+Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration
+
+
+# Checklist:
+
+- [ ] My code follows the style guidelines of this project
+- [ ] I have performed a self-review of my code
+- [ ] I have commented my code, particularly in hard-to-understand areas
+- [ ] I have made corresponding changes to the documentation
+- [ ] My changes generate no new warnings
+- [ ] I have added tests that prove my fix is effective or that my feature works
+- [ ] New and existing unit tests pass locally with my changes
+- [ ] Any dependent changes have been merged and published in downstream modules
\ No newline at end of file
diff --git a/src/app/api/auth/[...nextauth]/options.ts b/src/app/api/auth/[...nextauth]/options.ts
deleted file mode 100644
index 0f139217..00000000
--- a/src/app/api/auth/[...nextauth]/options.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { NextAuthOptions } from "next-auth";
-import GitHubProvider from "next-auth/providers/github";
-import DiscordProvider from "next-auth/providers/discord";
-
-export const options: NextAuthOptions = {
- providers: [
- GitHubProvider({
- clientId: process.env.GITHUB_ID as string,
- clientSecret: process.env.GITHUB_SECRET as string,
- }),
- DiscordProvider({
- clientId: process.env.DISCORD_ID as string,
- clientSecret: process.env.DISCORD_SECRET as string,
- }),
- ],
-};
diff --git a/src/app/api/auth/[...nextauth]/route.ts b/src/app/api/auth/[...nextauth]/route.ts
deleted file mode 100644
index 9ef211f1..00000000
--- a/src/app/api/auth/[...nextauth]/route.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import NextAuth from "next-auth/next";
-import { options } from "./options";
-
-// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
-const handler = NextAuth(options);
-
-export { handler as GET, handler as POST };
diff --git a/src/app/api/test/route.ts b/src/app/api/test/route.ts
deleted file mode 100644
index a23d1a77..00000000
--- a/src/app/api/test/route.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-// for testing purposes
-
-import { NextResponse } from "next/server";
-
-export function GET() {
- return NextResponse.json("hi there");
-}
diff --git a/src/app/counter/counter.test.tsx b/src/app/counter/counter.test.tsx
deleted file mode 100644
index 1722f3ec..00000000
--- a/src/app/counter/counter.test.tsx
+++ /dev/null
@@ -1,10 +0,0 @@
-import { render } from "@testing-library/react";
-import CounterPage from "./page";
-import { StoreProvider } from "@/components";
-it("should render the component", () => {
- render(
-
-
- ,
- );
-});
diff --git a/src/app/counter/index.ts b/src/app/counter/index.ts
deleted file mode 100644
index e5dfbeb8..00000000
--- a/src/app/counter/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { default as CounterPage } from "./page";
diff --git a/src/app/counter/page.tsx b/src/app/counter/page.tsx
deleted file mode 100644
index fbb2741c..00000000
--- a/src/app/counter/page.tsx
+++ /dev/null
@@ -1,48 +0,0 @@
-// test, remove later
-
-"use client";
-
-import {
- decrement,
- increment,
- selectCount,
- useAppDispatch,
- useAppSelector,
-} from "@/store";
-
-function CounterPage() {
- const counter = useAppSelector(selectCount);
- const dispatch = useAppDispatch();
-
- function incrementClick() {
- dispatch(increment());
- }
-
- function handleDecrement() {
- dispatch(decrement());
- }
-
- return (
-
{own_idea ? (
diff --git a/src/app/ideation/components/CreateIdeationContainer.tsx b/src/app/ideation/components/CreateIdeationContainer.tsx
index b999be75..7677845b 100644
--- a/src/app/ideation/components/CreateIdeationContainer.tsx
+++ b/src/app/ideation/components/CreateIdeationContainer.tsx
@@ -3,13 +3,22 @@ import { Button } from "@/components";
function CreateIdeationContainer() {
return (
-
-
+
+
+
+
+
+
-
+
What is your Voyage project idea & vision?
-
+
We value your ideas! Share your ideas on what our project should be.
Describe your vision to capture what it does and the benefit it will
bring to users.
@@ -17,7 +26,7 @@ function CreateIdeationContainer() {