├── .babelrc
├── .github
├── FUNDING.yml
└── workflows
│ ├── cypress.yml
│ └── unit.yml
├── .gitignore
├── .nvmrc
├── .storybook
├── addons.js
└── config.js
├── LICENSE
├── README.md
├── cypress.json
├── cypress
├── .eslintrc
├── fixtures
│ ├── english-monthly.json
│ ├── english.json
│ ├── javascript-monthly.json
│ ├── javascript.json
│ ├── trending-2.json
│ └── trending.json
├── integration
│ ├── dark-mode.js
│ ├── empty-state.js
│ ├── error-state.js
│ ├── feeling-lucky.js
│ ├── load-repositories.js
│ ├── scroll-icon.js
│ └── selectors.js
├── plugins
│ └── index.js
└── support
│ ├── commands.js
│ └── index.js
├── images
├── 1280x640.jpg
├── 1280x640_dark.jpg
├── 1280x800.jpg
├── 1280x800_dark.jpg
├── design.sketch
├── hero.jpeg
├── hero.svg
├── icon.png
├── screenshot.jpg
├── tile.jpg
├── tile2.jpg
└── tile3.jpg
├── package.json
├── public
├── 128.png
├── 16.png
├── 48.png
├── 512.png
├── 512_dark.png
├── ga.js
├── index.html
└── manifest.json
├── src
├── App.js
├── Main.js
├── background
│ ├── __tests__
│ │ └── startRequest.js
│ ├── index.js
│ └── startRequest.js
├── components
│ ├── BottomIcons.js
│ ├── ContentPlaceholder.js
│ ├── EmptyState.js
│ ├── Fade.js
│ ├── Footer.js
│ ├── Icon.js
│ ├── InfoItem.js
│ ├── LanguageSelect.js
│ ├── LastUpdated.js
│ ├── NetworkError.js
│ ├── PeriodSelect.js
│ ├── RepositoriesList.js
│ ├── RepositoryCard.js
│ ├── ScrollTop.js
│ ├── Select.js
│ ├── SpokenLanguageSelect.js
│ ├── TopBar.js
│ ├── index.js
│ └── stories
│ │ ├── Components.stories.js
│ │ ├── Icon.stories.js
│ │ └── NetworkError.stories.js
├── dev-tools
│ ├── dev-tools.js
│ └── load.js
├── feature-toggles.js
├── fonts
│ ├── index.js
│ └── tt-commons
│ │ ├── TTCommons-Black.eot
│ │ ├── TTCommons-Black.ttf
│ │ ├── TTCommons-Black.woff
│ │ ├── TTCommons-BlackItalic.eot
│ │ ├── TTCommons-BlackItalic.ttf
│ │ ├── TTCommons-BlackItalic.woff
│ │ ├── TTCommons-Bold.eot
│ │ ├── TTCommons-Bold.ttf
│ │ ├── TTCommons-Bold.woff
│ │ ├── TTCommons-BoldItalic.eot
│ │ ├── TTCommons-BoldItalic.ttf
│ │ ├── TTCommons-BoldItalic.woff
│ │ ├── TTCommons-DemiBold.eot
│ │ ├── TTCommons-DemiBold.ttf
│ │ ├── TTCommons-DemiBold.woff
│ │ ├── TTCommons-DemiBoldItalic.eot
│ │ ├── TTCommons-DemiBoldItalic.ttf
│ │ ├── TTCommons-DemiBoldItalic.woff
│ │ ├── TTCommons-ExtraBold.eot
│ │ ├── TTCommons-ExtraBold.ttf
│ │ ├── TTCommons-ExtraBold.woff
│ │ ├── TTCommons-ExtraBoldItalic.eot
│ │ ├── TTCommons-ExtraBoldItalic.ttf
│ │ ├── TTCommons-ExtraBoldItalic.woff
│ │ ├── TTCommons-ExtraLight.eot
│ │ ├── TTCommons-ExtraLight.ttf
│ │ ├── TTCommons-ExtraLight.woff
│ │ ├── TTCommons-ExtraLightItalic.eot
│ │ ├── TTCommons-ExtraLightItalic.ttf
│ │ ├── TTCommons-ExtraLightItalic.woff
│ │ ├── TTCommons-Italic.eot
│ │ ├── TTCommons-Italic.ttf
│ │ ├── TTCommons-Italic.woff
│ │ ├── TTCommons-Light.eot
│ │ ├── TTCommons-Light.ttf
│ │ ├── TTCommons-Light.woff
│ │ ├── TTCommons-LightItalic.eot
│ │ ├── TTCommons-LightItalic.ttf
│ │ ├── TTCommons-LightItalic.woff
│ │ ├── TTCommons-Medium.eot
│ │ ├── TTCommons-Medium.ttf
│ │ ├── TTCommons-Medium.woff
│ │ ├── TTCommons-MediumItalic.eot
│ │ ├── TTCommons-MediumItalic.ttf
│ │ ├── TTCommons-MediumItalic.woff
│ │ ├── TTCommons-Regular.eot
│ │ ├── TTCommons-Regular.ttf
│ │ ├── TTCommons-Regular.woff
│ │ ├── TTCommons-Thin.eot
│ │ ├── TTCommons-Thin.ttf
│ │ ├── TTCommons-Thin.woff
│ │ ├── TTCommons-ThinItalic.eot
│ │ ├── TTCommons-ThinItalic.ttf
│ │ ├── TTCommons-ThinItalic.woff
│ │ └── style.css
├── global.css
├── helpers
│ ├── github.js
│ └── localStorage.js
├── hooks.js
├── hooks
│ ├── useLocalStorage.js
│ └── useWindowScroll.js
├── images
│ ├── author.svg
│ ├── chrome.svg
│ ├── cross.svg
│ ├── empty.svg
│ ├── forks.svg
│ ├── github.svg
│ ├── heart.svg
│ ├── logo.svg
│ ├── moon.svg
│ ├── random.svg
│ ├── repos.svg
│ ├── setting.svg
│ ├── star-filled.svg
│ ├── sun.svg
│ ├── top.svg
│ └── warning.svg
├── index.js
├── setupTests.js
└── theme.js
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["react-app"]
3 | }
4 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: # Replace with a single Patreon username
5 | open_collective:
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: ['https://www.buymeacoffee.com/huchenme']
13 |
--------------------------------------------------------------------------------
/.github/workflows/cypress.yml:
--------------------------------------------------------------------------------
1 | name: Cypress Test
2 | on: [push]
3 | jobs:
4 | cypress-run:
5 | runs-on: ubuntu-latest
6 | steps:
7 | - name: Checkout
8 | uses: actions/checkout@v2
9 | - name: Setup Node
10 | uses: actions/setup-node@v1
11 | with:
12 | node-version: 12.x
13 | - name: Install packages
14 | run: yarn install
15 | - name: Cypress run
16 | uses: cypress-io/github-action@v1
17 | with:
18 | record: true
19 | start: yarn start:nobrowser
20 | wait-on: 'http://localhost:3000'
21 | env:
22 | CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
23 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
24 |
--------------------------------------------------------------------------------
/.github/workflows/unit.yml:
--------------------------------------------------------------------------------
1 | name: Unit test and build
2 | on: [push]
3 | jobs:
4 | build:
5 | runs-on: ubuntu-latest
6 | steps:
7 | - name: Checkout
8 | uses: actions/checkout@v2
9 | - name: Setup Node
10 | uses: actions/setup-node@v1
11 | with:
12 | node-version: 12.x
13 | - run: yarn install
14 | - run: yarn build
15 | - run: yarn test
16 | env:
17 | CI: true
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 | /*.zip
14 |
15 | # misc
16 | .DS_Store
17 | .env.local
18 | .env.development.local
19 | .env.test.local
20 | .env.production.local
21 |
22 | npm-debug.log*
23 | yarn-debug.log*
24 | yarn-error.log*
25 |
26 | /cypress/videos
27 | /cypress/screenshots
28 |
29 | /storybook-static
30 | *.local.js
31 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | v12.10.0
2 |
--------------------------------------------------------------------------------
/.storybook/addons.js:
--------------------------------------------------------------------------------
1 | import '@storybook/addon-actions/register';
2 | import '@storybook/addon-links/register';
3 | import '@storybook/addon-notes/register';
4 |
--------------------------------------------------------------------------------
/.storybook/config.js:
--------------------------------------------------------------------------------
1 | import { configure, addDecorator } from '@storybook/react';
2 | import centered from '@storybook/addon-centered/react';
3 |
4 | import '../src/global.css';
5 |
6 | // automatically import all files ending in *.stories.js
7 | const req = require.context('../src', true, /\.stories\.js$/);
8 | function loadStories() {
9 | req.keys().forEach(filename => req(filename));
10 | }
11 |
12 | addDecorator(centered);
13 |
14 | configure(loadStories, module);
15 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 | Copyright (c) 2019 Hu Chen
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy
5 | of this software and associated documentation files (the "Software"), to deal
6 | in the Software without restriction, including without limitation the rights
7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the Software is
9 | furnished to do so, subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in all
12 | copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://chrome.google.com/webstore/detail/hacker-tab/ibomigipadcieapbemkegkmadbbanbgm)
2 | [](https://chrome.google.com/webstore/detail/hacker-tab/ibomigipadcieapbemkegkmadbbanbgm/reviews)
3 | [](https://travis-ci.org/huchenme/hacker-tab-extension)
4 | [](https://github.com/huchenme/hacker-tab-extension/blob/master/LICENSE)
5 |
6 | ## What is Hacker Tab Extension
7 |
8 | Hacker Tab replace browser new tab screen with GitHub trending projects, so that developer get to know trending repositories everyday. It loads trending project periodically in background so you do not need to wait for loading every time you open a new tab.
9 |
10 | 
11 |
12 | ## Install
13 |
14 |
15 |
16 | Trusted by developers! Install Hacker Tab from [Chrome Web Store](https://chrome.google.com/webstore/detail/hacker-tab/ibomigipadcieapbemkegkmadbbanbgm).
17 |
18 | ## View Online
19 |
20 | [View Online](https://hacker-tab-extension.now.sh) version of extension.
21 |
22 | ## Backers
23 |
24 | Thank you to all our backers! 🙏
25 |
26 |
27 |
28 | ## Feedback
29 |
30 | Just write me an [email](mailto:chen@huchen.dev), or create an [issue](issues).
31 |
32 | ## Give us a rating
33 |
34 | If you enjoy using it, please help to write a review at [Chrome Web Store](https://chrome.google.com/webstore/detail/hacker-tab/ibomigipadcieapbemkegkmadbbanbgm), and star this repo. This will motivate me a lot :)
35 |
36 | ## Related
37 |
38 | - [github-trending-api](https://github.com/huchenme/github-trending-api): The missing APIs for GitHub trending projects and developers.
39 | - [How to use React.js to create a cross-browser extension in 5 minutes](https://levelup.gitconnected.com/how-to-use-react-js-to-create-chrome-extension-in-5-minutes-2ddb11899815?source=friends_link&sk=055e5c73e0dd11fd8cb25130242f388e).
40 | - Hacker Tab on [Product Hunt](https://www.producthunt.com/posts/hacker-tab).
41 | - [Internal Components](https://hacker-tab-components.netlify.com)
42 |
43 | ## Disclaimer
44 |
45 | Hacker Tab is not affiliated with, sponsored by, or endorsed by GitHub Inc.
46 |
--------------------------------------------------------------------------------
/cypress.json:
--------------------------------------------------------------------------------
1 | {
2 | "baseUrl": "http://localhost:3000",
3 | "projectId": "wrmpdh"
4 | }
5 |
--------------------------------------------------------------------------------
/cypress/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 | "env": { "cypress/globals": true },
4 | "extends": ["react-app", "plugin:cypress/recommended"],
5 | "plugins": ["cypress"]
6 | }
7 |
--------------------------------------------------------------------------------
/cypress/fixtures/trending-2.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "author": "bottlerocket-os",
4 | "name": "bottlerocket",
5 | "avatar": "https://github.com/bottlerocket-os.png",
6 | "url": "https://github.com/bottlerocket-os/bottlerocket",
7 | "description": "An operating system designed for hosting containers",
8 | "language": "Rust",
9 | "languageColor": "#dea584",
10 | "stars": 1758,
11 | "forks": 59,
12 | "currentPeriodStars": 1094,
13 | "builtBy": [
14 | {
15 | "username": "tjkirch",
16 | "href": "https://github.com/tjkirch",
17 | "avatar": "https://avatars3.githubusercontent.com/u/13994"
18 | },
19 | {
20 | "username": "iliana",
21 | "href": "https://github.com/iliana",
22 | "avatar": "https://avatars3.githubusercontent.com/u/52814"
23 | },
24 | {
25 | "username": "bcressey",
26 | "href": "https://github.com/bcressey",
27 | "avatar": "https://avatars1.githubusercontent.com/u/174814"
28 | },
29 | {
30 | "username": "jahkeup",
31 | "href": "https://github.com/jahkeup",
32 | "avatar": "https://avatars2.githubusercontent.com/u/1139752"
33 | },
34 | {
35 | "username": "etungsten",
36 | "href": "https://github.com/etungsten",
37 | "avatar": "https://avatars2.githubusercontent.com/u/52762042"
38 | }
39 | ]
40 | },
41 | {
42 | "author": "maxvoltar",
43 | "name": "photo-stream",
44 | "avatar": "https://github.com/maxvoltar.png",
45 | "url": "https://github.com/maxvoltar/photo-stream",
46 | "description": "Self-hosted, super simple photo stream",
47 | "language": "HTML",
48 | "languageColor": "#e34c26",
49 | "stars": 682,
50 | "forks": 93,
51 | "currentPeriodStars": 503,
52 | "builtBy": [
53 | {
54 | "username": "maxvoltar",
55 | "href": "https://github.com/maxvoltar",
56 | "avatar": "https://avatars3.githubusercontent.com/u/125779"
57 | },
58 | {
59 | "username": "benubois",
60 | "href": "https://github.com/benubois",
61 | "avatar": "https://avatars2.githubusercontent.com/u/133809"
62 | },
63 | {
64 | "username": "jadlimcaco",
65 | "href": "https://github.com/jadlimcaco",
66 | "avatar": "https://avatars0.githubusercontent.com/u/949200"
67 | },
68 | {
69 | "username": "mattsacks",
70 | "href": "https://github.com/mattsacks",
71 | "avatar": "https://avatars3.githubusercontent.com/u/194567"
72 | },
73 | {
74 | "username": "mikedholt",
75 | "href": "https://github.com/mikedholt",
76 | "avatar": "https://avatars0.githubusercontent.com/u/5240429"
77 | }
78 | ]
79 | },
80 | {
81 | "author": "pcm-dpc",
82 | "name": "COVID-19",
83 | "avatar": "https://github.com/pcm-dpc.png",
84 | "url": "https://github.com/pcm-dpc/COVID-19",
85 | "description": "COVID-19 Italia - Monitoraggio situazione",
86 | "stars": 1486,
87 | "forks": 284,
88 | "currentPeriodStars": 340,
89 | "builtBy": [
90 | {
91 | "username": "brucellino",
92 | "href": "https://github.com/brucellino",
93 | "avatar": "https://avatars0.githubusercontent.com/u/2115428"
94 | },
95 | {
96 | "username": "umbros",
97 | "href": "https://github.com/umbros",
98 | "avatar": "https://avatars1.githubusercontent.com/u/4085151"
99 | }
100 | ]
101 | },
102 | {
103 | "author": "redwoodjs",
104 | "name": "redwood",
105 | "avatar": "https://github.com/redwoodjs.png",
106 | "url": "https://github.com/redwoodjs/redwood",
107 | "description": "Bringing full-stack to the JAMstack.",
108 | "language": "JavaScript",
109 | "languageColor": "#f1e05a",
110 | "stars": 1898,
111 | "forks": 45,
112 | "currentPeriodStars": 530,
113 | "builtBy": [
114 | {
115 | "username": "peterp",
116 | "href": "https://github.com/peterp",
117 | "avatar": "https://avatars2.githubusercontent.com/u/44849"
118 | },
119 | {
120 | "username": "thedavidprice",
121 | "href": "https://github.com/thedavidprice",
122 | "avatar": "https://avatars2.githubusercontent.com/u/2951"
123 | },
124 | {
125 | "username": "mojombo",
126 | "href": "https://github.com/mojombo",
127 | "avatar": "https://avatars1.githubusercontent.com/u/1"
128 | },
129 | {
130 | "username": "cannikin",
131 | "href": "https://github.com/cannikin",
132 | "avatar": "https://avatars0.githubusercontent.com/u/300"
133 | },
134 | {
135 | "username": "adrianmg",
136 | "href": "https://github.com/adrianmg",
137 | "avatar": "https://avatars0.githubusercontent.com/u/589285"
138 | }
139 | ]
140 | },
141 | {
142 | "author": "google-research",
143 | "name": "google-research",
144 | "avatar": "https://github.com/google-research.png",
145 | "url": "https://github.com/google-research/google-research",
146 | "description": "Google Research",
147 | "language": "Jupyter Notebook",
148 | "languageColor": "#DA5B0B",
149 | "stars": 8356,
150 | "forks": 1488,
151 | "currentPeriodStars": 422,
152 | "builtBy": [
153 | {
154 | "username": "pdpino",
155 | "href": "https://github.com/pdpino",
156 | "avatar": "https://avatars1.githubusercontent.com/u/20805451"
157 | },
158 | {
159 | "username": "sun51",
160 | "href": "https://github.com/sun51",
161 | "avatar": "https://avatars3.githubusercontent.com/u/3901200"
162 | },
163 | {
164 | "username": "agutkin",
165 | "href": "https://github.com/agutkin",
166 | "avatar": "https://avatars0.githubusercontent.com/u/35786058"
167 | },
168 | {
169 | "username": "dustinvtran",
170 | "href": "https://github.com/dustinvtran",
171 | "avatar": "https://avatars2.githubusercontent.com/u/2569867"
172 | },
173 | {
174 | "username": "andrewluchen",
175 | "href": "https://github.com/andrewluchen",
176 | "avatar": "https://avatars1.githubusercontent.com/u/6128079"
177 | }
178 | ]
179 | },
180 | {
181 | "author": "tandasat",
182 | "name": "MiniVisorPkg",
183 | "avatar": "https://github.com/tandasat.png",
184 | "url": "https://github.com/tandasat/MiniVisorPkg",
185 | "description": "The research UEFI hypervisor that supports booting an operating system.",
186 | "language": "C",
187 | "languageColor": "#555555",
188 | "stars": 95,
189 | "forks": 26,
190 | "currentPeriodStars": 36,
191 | "builtBy": [
192 | {
193 | "username": "tandasat",
194 | "href": "https://github.com/tandasat",
195 | "avatar": "https://avatars1.githubusercontent.com/u/1620923"
196 | },
197 | {
198 | "username": "brucedang",
199 | "href": "https://github.com/brucedang",
200 | "avatar": "https://avatars3.githubusercontent.com/u/943548"
201 | }
202 | ]
203 | },
204 | {
205 | "author": "CSSEGISandData",
206 | "name": "COVID-19",
207 | "avatar": "https://github.com/CSSEGISandData.png",
208 | "url": "https://github.com/CSSEGISandData/COVID-19",
209 | "description": "Novel Coronavirus (COVID-19) Cases, provided by JHU CSSE",
210 | "stars": 6953,
211 | "forks": 2467,
212 | "currentPeriodStars": 658,
213 | "builtBy": [
214 | {
215 | "username": "CSSEGISandData",
216 | "href": "https://github.com/CSSEGISandData",
217 | "avatar": "https://avatars3.githubusercontent.com/u/60674295"
218 | },
219 | {
220 | "username": "hongru94",
221 | "href": "https://github.com/hongru94",
222 | "avatar": "https://avatars3.githubusercontent.com/u/47940478"
223 | },
224 | {
225 | "username": "enshengdong",
226 | "href": "https://github.com/enshengdong",
227 | "avatar": "https://avatars0.githubusercontent.com/u/10015024"
228 | }
229 | ]
230 | },
231 | {
232 | "author": "nndl",
233 | "name": "nndl.github.io",
234 | "avatar": "https://github.com/nndl.png",
235 | "url": "https://github.com/nndl/nndl.github.io",
236 | "description": "《神经网络与深度学习》 邱锡鹏著 Neural Network and Deep Learning",
237 | "language": "HTML",
238 | "languageColor": "#e34c26",
239 | "stars": 11097,
240 | "forks": 2491,
241 | "currentPeriodStars": 56,
242 | "builtBy": [
243 | {
244 | "username": "xpqiu",
245 | "href": "https://github.com/xpqiu",
246 | "avatar": "https://avatars0.githubusercontent.com/u/6408146"
247 | },
248 | {
249 | "username": "JerrikEph",
250 | "href": "https://github.com/JerrikEph",
251 | "avatar": "https://avatars0.githubusercontent.com/u/17830427"
252 | },
253 | {
254 | "username": "QipengGuo",
255 | "href": "https://github.com/QipengGuo",
256 | "avatar": "https://avatars0.githubusercontent.com/u/8382210"
257 | },
258 | {
259 | "username": "tys1998",
260 | "href": "https://github.com/tys1998",
261 | "avatar": "https://avatars0.githubusercontent.com/u/33472759"
262 | },
263 | {
264 | "username": "chenkaiyu1997",
265 | "href": "https://github.com/chenkaiyu1997",
266 | "avatar": "https://avatars2.githubusercontent.com/u/16744047"
267 | }
268 | ]
269 | },
270 | {
271 | "author": "meshtastic",
272 | "name": "Meshtastic-esp32",
273 | "avatar": "https://github.com/meshtastic.png",
274 | "url": "https://github.com/meshtastic/Meshtastic-esp32",
275 | "description": "Device code for the Meshtastic ski/hike/fly/Signal-chat GPS radio",
276 | "language": "C++",
277 | "languageColor": "#f34b7d",
278 | "stars": 337,
279 | "forks": 17,
280 | "currentPeriodStars": 163,
281 | "builtBy": [
282 | {
283 | "username": "geeksville",
284 | "href": "https://github.com/geeksville",
285 | "avatar": "https://avatars3.githubusercontent.com/u/225513"
286 | },
287 | {
288 | "username": "claesg",
289 | "href": "https://github.com/claesg",
290 | "avatar": "https://avatars2.githubusercontent.com/u/13845590"
291 | },
292 | {
293 | "username": "girtsf",
294 | "href": "https://github.com/girtsf",
295 | "avatar": "https://avatars0.githubusercontent.com/u/260191"
296 | },
297 | {
298 | "username": "gitter-badger",
299 | "href": "https://github.com/gitter-badger",
300 | "avatar": "https://avatars3.githubusercontent.com/u/8518239"
301 | }
302 | ]
303 | },
304 | {
305 | "author": "google-research",
306 | "name": "electra",
307 | "avatar": "https://github.com/google-research.png",
308 | "url": "https://github.com/google-research/electra",
309 | "description": "ELECTRA: Pre-training Text Encoders as Discriminators Rather Than Generators",
310 | "language": "Python",
311 | "languageColor": "#3572A5",
312 | "stars": 355,
313 | "forks": 31,
314 | "currentPeriodStars": 96,
315 | "builtBy": [
316 | {
317 | "username": "clarkkev",
318 | "href": "https://github.com/clarkkev",
319 | "avatar": "https://avatars3.githubusercontent.com/u/1091306"
320 | },
321 | {
322 | "username": "stefan-it",
323 | "href": "https://github.com/stefan-it",
324 | "avatar": "https://avatars0.githubusercontent.com/u/20651387"
325 | },
326 | {
327 | "username": "michelole",
328 | "href": "https://github.com/michelole",
329 | "avatar": "https://avatars1.githubusercontent.com/u/1688126"
330 | }
331 | ]
332 | },
333 | {
334 | "author": "doocs",
335 | "name": "advanced-java",
336 | "avatar": "https://github.com/doocs.png",
337 | "url": "https://github.com/doocs/advanced-java",
338 | "description": "😮 互联网 Java 工程师进阶知识完全扫盲:涵盖高并发、分布式、高可用、微服务、海量数据处理等领域知识,后端同学必看,前端同学也可学习",
339 | "language": "Java",
340 | "languageColor": "#b07219",
341 | "stars": 40079,
342 | "forks": 11039,
343 | "currentPeriodStars": 133,
344 | "builtBy": [
345 | {
346 | "username": "yanglbme",
347 | "href": "https://github.com/yanglbme",
348 | "avatar": "https://avatars3.githubusercontent.com/u/21008209"
349 | },
350 | {
351 | "username": "ImgBotApp",
352 | "href": "https://github.com/ImgBotApp",
353 | "avatar": "https://avatars2.githubusercontent.com/u/31427850"
354 | },
355 | {
356 | "username": "lihangqi",
357 | "href": "https://github.com/lihangqi",
358 | "avatar": "https://avatars2.githubusercontent.com/u/26339055"
359 | },
360 | {
361 | "username": "huifer",
362 | "href": "https://github.com/huifer",
363 | "avatar": "https://avatars0.githubusercontent.com/u/26766909"
364 | },
365 | {
366 | "username": "chenqimiao",
367 | "href": "https://github.com/chenqimiao",
368 | "avatar": "https://avatars1.githubusercontent.com/u/15151483"
369 | }
370 | ]
371 | },
372 | {
373 | "author": "pytorch",
374 | "name": "pytorch",
375 | "avatar": "https://github.com/pytorch.png",
376 | "url": "https://github.com/pytorch/pytorch",
377 | "description": "Tensors and Dynamic neural networks in Python with strong GPU acceleration",
378 | "language": "C++",
379 | "languageColor": "#f34b7d",
380 | "stars": 36846,
381 | "forks": 9358,
382 | "currentPeriodStars": 55,
383 | "builtBy": [
384 | {
385 | "username": "ezyang",
386 | "href": "https://github.com/ezyang",
387 | "avatar": "https://avatars0.githubusercontent.com/u/13564"
388 | },
389 | {
390 | "username": "soumith",
391 | "href": "https://github.com/soumith",
392 | "avatar": "https://avatars1.githubusercontent.com/u/1310570"
393 | },
394 | {
395 | "username": "gchanan",
396 | "href": "https://github.com/gchanan",
397 | "avatar": "https://avatars1.githubusercontent.com/u/3768583"
398 | },
399 | {
400 | "username": "apaszke",
401 | "href": "https://github.com/apaszke",
402 | "avatar": "https://avatars0.githubusercontent.com/u/4583066"
403 | },
404 | {
405 | "username": "Yangqing",
406 | "href": "https://github.com/Yangqing",
407 | "avatar": "https://avatars3.githubusercontent.com/u/551151"
408 | }
409 | ]
410 | },
411 | {
412 | "author": "EvgenyKashin",
413 | "name": "stylegan2-distillation",
414 | "avatar": "https://github.com/EvgenyKashin.png",
415 | "url": "https://github.com/EvgenyKashin/stylegan2-distillation",
416 | "description": "",
417 | "stars": 273,
418 | "forks": 18,
419 | "currentPeriodStars": 88,
420 | "builtBy": [
421 | {
422 | "username": "EvgenyKashin",
423 | "href": "https://github.com/EvgenyKashin",
424 | "avatar": "https://avatars2.githubusercontent.com/u/21174773"
425 | }
426 | ]
427 | },
428 | {
429 | "author": "mai-lang-chai",
430 | "name": "Middleware-Vulnerability-detection",
431 | "avatar": "https://github.com/mai-lang-chai.png",
432 | "url": "https://github.com/mai-lang-chai/Middleware-Vulnerability-detection",
433 | "description": "CVE、CMS、中间件漏洞检测利用合集 Since 2019-9-15",
434 | "language": "Python",
435 | "languageColor": "#3572A5",
436 | "stars": 349,
437 | "forks": 81,
438 | "currentPeriodStars": 47,
439 | "builtBy": [
440 | {
441 | "username": "mai-lang-chai",
442 | "href": "https://github.com/mai-lang-chai",
443 | "avatar": "https://avatars1.githubusercontent.com/u/36095584"
444 | }
445 | ]
446 | },
447 | {
448 | "author": "MhdHejazi",
449 | "name": "CoronaTracker",
450 | "avatar": "https://github.com/MhdHejazi.png",
451 | "url": "https://github.com/MhdHejazi/CoronaTracker",
452 | "description": "Coronavirus tracker app for iOS & macOS with map & charts",
453 | "language": "Swift",
454 | "languageColor": "#ffac45",
455 | "stars": 207,
456 | "forks": 22,
457 | "currentPeriodStars": 57,
458 | "builtBy": [
459 | {
460 | "username": "MhdHejazi",
461 | "href": "https://github.com/MhdHejazi",
462 | "avatar": "https://avatars1.githubusercontent.com/u/121827"
463 | }
464 | ]
465 | },
466 | {
467 | "author": "taviso",
468 | "name": "avscript",
469 | "avatar": "https://github.com/taviso.png",
470 | "url": "https://github.com/taviso/avscript",
471 | "description": "Avast JavaScript Interactive Shell",
472 | "language": "C",
473 | "languageColor": "#555555",
474 | "stars": 485,
475 | "forks": 32,
476 | "currentPeriodStars": 171,
477 | "builtBy": [
478 | {
479 | "username": "taviso",
480 | "href": "https://github.com/taviso",
481 | "avatar": "https://avatars0.githubusercontent.com/u/123814"
482 | },
483 | {
484 | "username": "Vipul97",
485 | "href": "https://github.com/Vipul97",
486 | "avatar": "https://avatars2.githubusercontent.com/u/16150834"
487 | }
488 | ]
489 | },
490 | {
491 | "author": "donnemartin",
492 | "name": "system-design-primer",
493 | "avatar": "https://github.com/donnemartin.png",
494 | "url": "https://github.com/donnemartin/system-design-primer",
495 | "description": "Learn how to design large-scale systems. Prep for the system design interview. Includes Anki flashcards.",
496 | "language": "Python",
497 | "languageColor": "#3572A5",
498 | "stars": 84966,
499 | "forks": 14435,
500 | "currentPeriodStars": 148,
501 | "builtBy": [
502 | {
503 | "username": "donnemartin",
504 | "href": "https://github.com/donnemartin",
505 | "avatar": "https://avatars0.githubusercontent.com/u/5458997"
506 | },
507 | {
508 | "username": "satob",
509 | "href": "https://github.com/satob",
510 | "avatar": "https://avatars0.githubusercontent.com/u/171818"
511 | },
512 | {
513 | "username": "fluency03",
514 | "href": "https://github.com/fluency03",
515 | "avatar": "https://avatars3.githubusercontent.com/u/7440735"
516 | },
517 | {
518 | "username": "antongulikov",
519 | "href": "https://github.com/antongulikov",
520 | "avatar": "https://avatars1.githubusercontent.com/u/6084440"
521 | },
522 | {
523 | "username": "fabriziocucci",
524 | "href": "https://github.com/fabriziocucci",
525 | "avatar": "https://avatars0.githubusercontent.com/u/8156463"
526 | }
527 | ]
528 | },
529 | {
530 | "author": "CTF-MissFeng",
531 | "name": "bayonet",
532 | "avatar": "https://github.com/CTF-MissFeng.png",
533 | "url": "https://github.com/CTF-MissFeng/bayonet",
534 | "description": "bayonet是一款src资产管理系统,从子域名、端口服务、漏洞、爬虫等一体化的资产管理系统",
535 | "language": "Python",
536 | "languageColor": "#3572A5",
537 | "stars": 272,
538 | "forks": 42,
539 | "currentPeriodStars": 48,
540 | "builtBy": [
541 | {
542 | "username": "CTF-MissFeng",
543 | "href": "https://github.com/CTF-MissFeng",
544 | "avatar": "https://avatars0.githubusercontent.com/u/38177965"
545 | }
546 | ]
547 | },
548 | {
549 | "author": "PizzaPokerGuy",
550 | "name": "ultimate-coding-resources",
551 | "avatar": "https://github.com/PizzaPokerGuy.png",
552 | "url": "https://github.com/PizzaPokerGuy/ultimate-coding-resources",
553 | "description": "A collection of the best resources for programming, web development, computer science and more.",
554 | "stars": 1475,
555 | "forks": 146,
556 | "currentPeriodStars": 235,
557 | "builtBy": [
558 | {
559 | "username": "PizzaPokerGuy",
560 | "href": "https://github.com/PizzaPokerGuy",
561 | "avatar": "https://avatars0.githubusercontent.com/u/14266817"
562 | },
563 | {
564 | "username": "samedwards1989",
565 | "href": "https://github.com/samedwards1989",
566 | "avatar": "https://avatars3.githubusercontent.com/u/11388164"
567 | },
568 | {
569 | "username": "ahavensdaxko",
570 | "href": "https://github.com/ahavensdaxko",
571 | "avatar": "https://avatars0.githubusercontent.com/u/33287549"
572 | },
573 | {
574 | "username": "krishnadevz",
575 | "href": "https://github.com/krishnadevz",
576 | "avatar": "https://avatars2.githubusercontent.com/u/42638797"
577 | }
578 | ]
579 | },
580 | {
581 | "author": "Tencent",
582 | "name": "DVQA",
583 | "avatar": "https://github.com/Tencent.png",
584 | "url": "https://github.com/Tencent/DVQA",
585 | "description": "Deep learning-based Video Quality Assessment",
586 | "language": "Python",
587 | "languageColor": "#3572A5",
588 | "stars": 68,
589 | "forks": 14,
590 | "currentPeriodStars": 22,
591 | "builtBy": [
592 | {
593 | "username": "tommyhq",
594 | "href": "https://github.com/tommyhq",
595 | "avatar": "https://avatars1.githubusercontent.com/u/61727295"
596 | }
597 | ]
598 | },
599 | {
600 | "author": "emergenzeHack",
601 | "name": "covid19italia",
602 | "avatar": "https://github.com/emergenzeHack.png",
603 | "url": "https://github.com/emergenzeHack/covid19italia",
604 | "description": "Condividiamo informazioni e segnalazioni sul COVID19",
605 | "language": "JavaScript",
606 | "languageColor": "#f1e05a",
607 | "stars": 25,
608 | "forks": 17,
609 | "currentPeriodStars": 8,
610 | "builtBy": [
611 | {
612 | "username": "mfortini",
613 | "href": "https://github.com/mfortini",
614 | "avatar": "https://avatars0.githubusercontent.com/u/1104926"
615 | },
616 | {
617 | "username": "iltempe",
618 | "href": "https://github.com/iltempe",
619 | "avatar": "https://avatars3.githubusercontent.com/u/6368214"
620 | },
621 | {
622 | "username": "avivace",
623 | "href": "https://github.com/avivace",
624 | "avatar": "https://avatars2.githubusercontent.com/u/14352721"
625 | },
626 | {
627 | "username": "tailot",
628 | "href": "https://github.com/tailot",
629 | "avatar": "https://avatars0.githubusercontent.com/u/40148896"
630 | },
631 | {
632 | "username": "olistik",
633 | "href": "https://github.com/olistik",
634 | "avatar": "https://avatars0.githubusercontent.com/u/21038"
635 | }
636 | ]
637 | },
638 | {
639 | "author": "iluwatar",
640 | "name": "java-design-patterns",
641 | "avatar": "https://github.com/iluwatar.png",
642 | "url": "https://github.com/iluwatar/java-design-patterns",
643 | "description": "Design patterns implemented in Java",
644 | "language": "Java",
645 | "languageColor": "#b07219",
646 | "stars": 56063,
647 | "forks": 18039,
648 | "currentPeriodStars": 85,
649 | "builtBy": [
650 | {
651 | "username": "iluwatar",
652 | "href": "https://github.com/iluwatar",
653 | "avatar": "https://avatars0.githubusercontent.com/u/582346"
654 | },
655 | {
656 | "username": "npathai",
657 | "href": "https://github.com/npathai",
658 | "avatar": "https://avatars0.githubusercontent.com/u/1792515"
659 | },
660 | {
661 | "username": "mikulucky",
662 | "href": "https://github.com/mikulucky",
663 | "avatar": "https://avatars2.githubusercontent.com/u/4526195"
664 | },
665 | {
666 | "username": "fluxw42",
667 | "href": "https://github.com/fluxw42",
668 | "avatar": "https://avatars2.githubusercontent.com/u/1545460"
669 | },
670 | {
671 | "username": "thomasoss",
672 | "href": "https://github.com/thomasoss",
673 | "avatar": "https://avatars2.githubusercontent.com/u/22516154"
674 | }
675 | ]
676 | },
677 | {
678 | "author": "lemire",
679 | "name": "fast_double_parser",
680 | "avatar": "https://github.com/lemire.png",
681 | "url": "https://github.com/lemire/fast_double_parser",
682 | "description": "Fast function to parse strings into double (binary64) floating-point values",
683 | "language": "C++",
684 | "languageColor": "#f34b7d",
685 | "stars": 221,
686 | "forks": 9,
687 | "currentPeriodStars": 70,
688 | "builtBy": [
689 | {
690 | "username": "lemire",
691 | "href": "https://github.com/lemire",
692 | "avatar": "https://avatars2.githubusercontent.com/u/391987"
693 | },
694 | {
695 | "username": "facontidavide",
696 | "href": "https://github.com/facontidavide",
697 | "avatar": "https://avatars1.githubusercontent.com/u/2822888"
698 | }
699 | ]
700 | },
701 | {
702 | "author": "blaCCkHatHacEEkr",
703 | "name": "PENTESTING-BIBLE",
704 | "avatar": "https://github.com/blaCCkHatHacEEkr.png",
705 | "url": "https://github.com/blaCCkHatHacEEkr/PENTESTING-BIBLE",
706 | "description": "This repository was created and developed by Ammar Amer @cry__pto Only. Updates to this repository will continue to arrive until the number of links reaches 10000 links & 10000 pdf files .Learn Ethical Hacking and penetration testing .hundreds of ethical hacking & penetration testing & red team & cyber security & computer science resources.",
707 | "stars": 4175,
708 | "forks": 821,
709 | "currentPeriodStars": 23,
710 | "builtBy": [
711 | {
712 | "username": "blaCCkHatHacEEkr",
713 | "href": "https://github.com/blaCCkHatHacEEkr",
714 | "avatar": "https://avatars0.githubusercontent.com/u/51203763"
715 | },
716 | {
717 | "username": "erjanmx",
718 | "href": "https://github.com/erjanmx",
719 | "avatar": "https://avatars3.githubusercontent.com/u/4899432"
720 | }
721 | ]
722 | },
723 | {
724 | "author": "livewire",
725 | "name": "livewire",
726 | "avatar": "https://github.com/livewire.png",
727 | "url": "https://github.com/livewire/livewire",
728 | "description": "A full-stack framework for Laravel that takes the pain out of building dynamic UIs.",
729 | "language": "PHP",
730 | "languageColor": "#4F5D95",
731 | "stars": 2354,
732 | "forks": 172,
733 | "currentPeriodStars": 36,
734 | "builtBy": [
735 | {
736 | "username": "calebporzio",
737 | "href": "https://github.com/calebporzio",
738 | "avatar": "https://avatars3.githubusercontent.com/u/3670578"
739 | },
740 | {
741 | "username": "lancepioch",
742 | "href": "https://github.com/lancepioch",
743 | "avatar": "https://avatars3.githubusercontent.com/u/1296882"
744 | },
745 | {
746 | "username": "tillkruss",
747 | "href": "https://github.com/tillkruss",
748 | "avatar": "https://avatars3.githubusercontent.com/u/665029"
749 | },
750 | {
751 | "username": "nuernbergerA",
752 | "href": "https://github.com/nuernbergerA",
753 | "avatar": "https://avatars2.githubusercontent.com/u/13331388"
754 | }
755 | ]
756 | }
757 | ]
758 |
--------------------------------------------------------------------------------
/cypress/fixtures/trending.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "author": "pcm-dpc",
4 | "name": "COVID-19",
5 | "avatar": "https://github.com/pcm-dpc.png",
6 | "url": "https://github.com/pcm-dpc/COVID-19",
7 | "description": "COVID-19 Italia - Monitoraggio situazione",
8 | "stars": 774,
9 | "forks": 144,
10 | "currentPeriodStars": 286,
11 | "builtBy": [
12 | {
13 | "username": "brucellino",
14 | "href": "https://github.com/brucellino",
15 | "avatar": "https://avatars0.githubusercontent.com/u/2115428"
16 | },
17 | {
18 | "username": "umbros",
19 | "href": "https://github.com/umbros",
20 | "avatar": "https://avatars1.githubusercontent.com/u/4085151"
21 | }
22 | ]
23 | },
24 | {
25 | "author": "ouyanghuiyu",
26 | "name": "chineseocr_lite",
27 | "avatar": "https://github.com/ouyanghuiyu.png",
28 | "url": "https://github.com/ouyanghuiyu/chineseocr_lite",
29 | "description": "超轻量级中文ocr,支持竖排文字识别, 支持ncnn推理 , psenet(8.5M) + crnn(6.3M) + anglenet(1.5M) 总模型仅17M",
30 | "language": "C++",
31 | "languageColor": "#f34b7d",
32 | "stars": 1753,
33 | "forks": 215,
34 | "currentPeriodStars": 400,
35 | "builtBy": [
36 | {
37 | "username": "ouyanghuiyu",
38 | "href": "https://github.com/ouyanghuiyu",
39 | "avatar": "https://avatars3.githubusercontent.com/u/42023607"
40 | }
41 | ]
42 | },
43 | {
44 | "author": "leelovejava",
45 | "name": "cloud2020",
46 | "avatar": "https://github.com/leelovejava.png",
47 | "url": "https://github.com/leelovejava/cloud2020",
48 | "description": "SpringCloud",
49 | "language": "Java",
50 | "languageColor": "#b07219",
51 | "stars": 76,
52 | "forks": 59,
53 | "currentPeriodStars": 12,
54 | "builtBy": [
55 | {
56 | "username": "leelovejava",
57 | "href": "https://github.com/leelovejava",
58 | "avatar": "https://avatars2.githubusercontent.com/u/20348936"
59 | }
60 | ]
61 | },
62 | {
63 | "author": "AobingJava",
64 | "name": "JavaFamily",
65 | "avatar": "https://github.com/AobingJava.png",
66 | "url": "https://github.com/AobingJava/JavaFamily",
67 | "description": "【互联网一线大厂面试+学习指南】进阶知识完全扫盲:涵盖高并发、分布式、高可用、微服务等领域知识,作者风格幽默,看起来津津有味,把学习当做一种乐趣,何乐而不为,后端同学必看,前端同学我保证你也看得懂,看不懂你加我微信骂我渣男就好了。",
68 | "stars": 7740,
69 | "forks": 1384,
70 | "currentPeriodStars": 143,
71 | "builtBy": [
72 | {
73 | "username": "AobingJava",
74 | "href": "https://github.com/AobingJava",
75 | "avatar": "https://avatars3.githubusercontent.com/u/41898583"
76 | }
77 | ]
78 | },
79 | {
80 | "author": "iikira",
81 | "name": "BaiduPCS-Go",
82 | "avatar": "https://github.com/iikira.png",
83 | "url": "https://github.com/iikira/BaiduPCS-Go",
84 | "description": "百度网盘客户端 - Go语言编写",
85 | "language": "Go",
86 | "languageColor": "#00ADD8",
87 | "stars": 21262,
88 | "forks": 3318,
89 | "currentPeriodStars": 169,
90 | "builtBy": [
91 | {
92 | "username": "iikira",
93 | "href": "https://github.com/iikira",
94 | "avatar": "https://avatars1.githubusercontent.com/u/19154488"
95 | },
96 | {
97 | "username": "apocelipes",
98 | "href": "https://github.com/apocelipes",
99 | "avatar": "https://avatars3.githubusercontent.com/u/21255940"
100 | },
101 | {
102 | "username": "daobee",
103 | "href": "https://github.com/daobee",
104 | "avatar": "https://avatars1.githubusercontent.com/u/21331325"
105 | },
106 | {
107 | "username": "hianghokung",
108 | "href": "https://github.com/hianghokung",
109 | "avatar": "https://avatars2.githubusercontent.com/u/22436288"
110 | },
111 | {
112 | "username": "88250",
113 | "href": "https://github.com/88250",
114 | "avatar": "https://avatars1.githubusercontent.com/u/873584"
115 | }
116 | ]
117 | },
118 | {
119 | "author": "Snailclimb",
120 | "name": "JavaGuide",
121 | "avatar": "https://github.com/Snailclimb.png",
122 | "url": "https://github.com/Snailclimb/JavaGuide",
123 | "description": "【Java学习+面试指南】 一份涵盖大部分Java程序员所需要掌握的核心知识。",
124 | "language": "Java",
125 | "languageColor": "#b07219",
126 | "stars": 71014,
127 | "forks": 24346,
128 | "currentPeriodStars": 219,
129 | "builtBy": [
130 | {
131 | "username": "Snailclimb",
132 | "href": "https://github.com/Snailclimb",
133 | "avatar": "https://avatars0.githubusercontent.com/u/29880145"
134 | },
135 | {
136 | "username": "Goose9527",
137 | "href": "https://github.com/Goose9527",
138 | "avatar": "https://avatars0.githubusercontent.com/u/43314997"
139 | },
140 | {
141 | "username": "LiWenGu",
142 | "href": "https://github.com/LiWenGu",
143 | "avatar": "https://avatars0.githubusercontent.com/u/15909210"
144 | },
145 | {
146 | "username": "Ryze-Zhao",
147 | "href": "https://github.com/Ryze-Zhao",
148 | "avatar": "https://avatars1.githubusercontent.com/u/38486503"
149 | },
150 | {
151 | "username": "fanofxiaofeng",
152 | "href": "https://github.com/fanofxiaofeng",
153 | "avatar": "https://avatars3.githubusercontent.com/u/3983683"
154 | }
155 | ]
156 | },
157 | {
158 | "author": "PizzaPokerGuy",
159 | "name": "ultimate-coding-resources",
160 | "avatar": "https://github.com/PizzaPokerGuy.png",
161 | "url": "https://github.com/PizzaPokerGuy/ultimate-coding-resources",
162 | "description": "A collection of the best resources for programming, web development, computer science and more.",
163 | "stars": 944,
164 | "forks": 97,
165 | "currentPeriodStars": 469,
166 | "builtBy": [
167 | {
168 | "username": "PizzaPokerGuy",
169 | "href": "https://github.com/PizzaPokerGuy",
170 | "avatar": "https://avatars0.githubusercontent.com/u/14266817"
171 | },
172 | {
173 | "username": "samedwards1989",
174 | "href": "https://github.com/samedwards1989",
175 | "avatar": "https://avatars3.githubusercontent.com/u/11388164"
176 | },
177 | {
178 | "username": "ahavensdaxko",
179 | "href": "https://github.com/ahavensdaxko",
180 | "avatar": "https://avatars0.githubusercontent.com/u/33287549"
181 | }
182 | ]
183 | },
184 | {
185 | "author": "CSSEGISandData",
186 | "name": "COVID-19",
187 | "avatar": "https://github.com/CSSEGISandData.png",
188 | "url": "https://github.com/CSSEGISandData/COVID-19",
189 | "description": "Novel Coronavirus (COVID-19) Cases, provided by JHU CSSE",
190 | "stars": 5609,
191 | "forks": 1908,
192 | "currentPeriodStars": 767,
193 | "builtBy": [
194 | {
195 | "username": "CSSEGISandData",
196 | "href": "https://github.com/CSSEGISandData",
197 | "avatar": "https://avatars3.githubusercontent.com/u/60674295"
198 | },
199 | {
200 | "username": "hongru94",
201 | "href": "https://github.com/hongru94",
202 | "avatar": "https://avatars3.githubusercontent.com/u/47940478"
203 | },
204 | {
205 | "username": "enshengdong",
206 | "href": "https://github.com/enshengdong",
207 | "avatar": "https://avatars0.githubusercontent.com/u/10015024"
208 | }
209 | ]
210 | },
211 | {
212 | "author": "amusi",
213 | "name": "CVPR2020-Code",
214 | "avatar": "https://github.com/amusi.png",
215 | "url": "https://github.com/amusi/CVPR2020-Code",
216 | "description": "CVPR 2020 论文开源项目合集",
217 | "stars": 444,
218 | "forks": 61,
219 | "currentPeriodStars": 130,
220 | "builtBy": [
221 | {
222 | "username": "amusi",
223 | "href": "https://github.com/amusi",
224 | "avatar": "https://avatars2.githubusercontent.com/u/22436957"
225 | }
226 | ]
227 | },
228 | {
229 | "author": "subnub",
230 | "name": "myDrive",
231 | "avatar": "https://github.com/subnub.png",
232 | "url": "https://github.com/subnub/myDrive",
233 | "description": "Node.js and mongoDB Google Drive Clone",
234 | "language": "JavaScript",
235 | "languageColor": "#f1e05a",
236 | "stars": 662,
237 | "forks": 78,
238 | "currentPeriodStars": 279,
239 | "builtBy": [
240 | {
241 | "username": "subnub",
242 | "href": "https://github.com/subnub",
243 | "avatar": "https://avatars3.githubusercontent.com/u/44621867"
244 | },
245 | {
246 | "username": "ImMaax",
247 | "href": "https://github.com/ImMaax",
248 | "avatar": "https://avatars2.githubusercontent.com/u/40642083"
249 | }
250 | ]
251 | },
252 | {
253 | "author": "ziishaned",
254 | "name": "learn-regex",
255 | "avatar": "https://github.com/ziishaned.png",
256 | "url": "https://github.com/ziishaned/learn-regex",
257 | "description": "Learn regex the easy way",
258 | "stars": 33842,
259 | "forks": 4628,
260 | "currentPeriodStars": 208,
261 | "builtBy": [
262 | {
263 | "username": "ziishaned",
264 | "href": "https://github.com/ziishaned",
265 | "avatar": "https://avatars2.githubusercontent.com/u/16267321"
266 | },
267 | {
268 | "username": "munkacsimark",
269 | "href": "https://github.com/munkacsimark",
270 | "avatar": "https://avatars2.githubusercontent.com/u/7120785"
271 | },
272 | {
273 | "username": "hjavadish",
274 | "href": "https://github.com/hjavadish",
275 | "avatar": "https://avatars2.githubusercontent.com/u/8628797"
276 | },
277 | {
278 | "username": "wicksome",
279 | "href": "https://github.com/wicksome",
280 | "avatar": "https://avatars2.githubusercontent.com/u/5036939"
281 | },
282 | {
283 | "username": "ImKifu",
284 | "href": "https://github.com/ImKifu",
285 | "avatar": "https://avatars2.githubusercontent.com/u/37338905"
286 | }
287 | ]
288 | },
289 | {
290 | "author": "Screetsec",
291 | "name": "TheFatRat",
292 | "avatar": "https://github.com/Screetsec.png",
293 | "url": "https://github.com/Screetsec/TheFatRat",
294 | "description": "Thefatrat a massive exploiting tool : Easy tool to generate backdoor and easy tool to post exploitation attack like browser attack and etc . This tool compiles a malware with popular payload and then the compiled malware can be execute on windows, android, mac . The malware that created with this tool also have an ability to bypass most AV softw…",
295 | "language": "C",
296 | "languageColor": "#555555",
297 | "stars": 3850,
298 | "forks": 1340,
299 | "currentPeriodStars": 64,
300 | "builtBy": [
301 | {
302 | "username": "Screetsec",
303 | "href": "https://github.com/Screetsec",
304 | "avatar": "https://avatars3.githubusercontent.com/u/17976841"
305 | },
306 | {
307 | "username": "peterpt",
308 | "href": "https://github.com/peterpt",
309 | "avatar": "https://avatars3.githubusercontent.com/u/7487321"
310 | },
311 | {
312 | "username": "mrusme",
313 | "href": "https://github.com/mrusme",
314 | "avatar": "https://avatars0.githubusercontent.com/u/151967"
315 | },
316 | {
317 | "username": "n0login",
318 | "href": "https://github.com/n0login",
319 | "avatar": "https://avatars2.githubusercontent.com/u/21091592"
320 | },
321 | {
322 | "username": "isfaaghyth",
323 | "href": "https://github.com/isfaaghyth",
324 | "avatar": "https://avatars2.githubusercontent.com/u/6775159"
325 | }
326 | ]
327 | },
328 | {
329 | "author": "guidovranken",
330 | "name": "vfuzz",
331 | "avatar": "https://github.com/guidovranken.png",
332 | "url": "https://github.com/guidovranken/vfuzz",
333 | "description": "vfuzz",
334 | "language": "C++",
335 | "languageColor": "#f34b7d",
336 | "stars": 119,
337 | "forks": 22,
338 | "currentPeriodStars": 44,
339 | "builtBy": [
340 | {
341 | "username": "guidovranken",
342 | "href": "https://github.com/guidovranken",
343 | "avatar": "https://avatars1.githubusercontent.com/u/6846644"
344 | }
345 | ]
346 | },
347 | {
348 | "author": "firstlookmedia",
349 | "name": "dangerzone",
350 | "avatar": "https://github.com/firstlookmedia.png",
351 | "url": "https://github.com/firstlookmedia/dangerzone",
352 | "description": "Take potentially dangerous PDFs, office documents, or images and convert them to a safe PDF",
353 | "language": "Python",
354 | "languageColor": "#3572A5",
355 | "stars": 626,
356 | "forks": 20,
357 | "currentPeriodStars": 135,
358 | "builtBy": [
359 | {
360 | "username": "micahflee",
361 | "href": "https://github.com/micahflee",
362 | "avatar": "https://avatars1.githubusercontent.com/u/156128"
363 | }
364 | ]
365 | },
366 | {
367 | "author": "ajeetdsouza",
368 | "name": "zoxide",
369 | "avatar": "https://github.com/ajeetdsouza.png",
370 | "url": "https://github.com/ajeetdsouza/zoxide",
371 | "description": "A fast cd command that learns your habits",
372 | "language": "Rust",
373 | "languageColor": "#dea584",
374 | "stars": 353,
375 | "forks": 11,
376 | "currentPeriodStars": 93,
377 | "builtBy": [
378 | {
379 | "username": "ajeetdsouza",
380 | "href": "https://github.com/ajeetdsouza",
381 | "avatar": "https://avatars3.githubusercontent.com/u/1777663"
382 | },
383 | {
384 | "username": "alin23",
385 | "href": "https://github.com/alin23",
386 | "avatar": "https://avatars1.githubusercontent.com/u/3819725"
387 | },
388 | {
389 | "username": "crazystylus",
390 | "href": "https://github.com/crazystylus",
391 | "avatar": "https://avatars1.githubusercontent.com/u/29002863"
392 | },
393 | {
394 | "username": "ErichDonGubler",
395 | "href": "https://github.com/ErichDonGubler",
396 | "avatar": "https://avatars0.githubusercontent.com/u/658538"
397 | },
398 | {
399 | "username": "cust0dian",
400 | "href": "https://github.com/cust0dian",
401 | "avatar": "https://avatars0.githubusercontent.com/u/389387"
402 | }
403 | ]
404 | },
405 | {
406 | "author": "six2dez",
407 | "name": "wahh_extras",
408 | "avatar": "https://github.com/six2dez.png",
409 | "url": "https://github.com/six2dez/wahh_extras",
410 | "description": "The Web Application Hacker's Handbook - Extra Content",
411 | "language": "Java",
412 | "languageColor": "#b07219",
413 | "stars": 262,
414 | "forks": 41,
415 | "currentPeriodStars": 75,
416 | "builtBy": [
417 | {
418 | "username": "six2dez",
419 | "href": "https://github.com/six2dez",
420 | "avatar": "https://avatars1.githubusercontent.com/u/24670991"
421 | }
422 | ]
423 | },
424 | {
425 | "author": "KeenS",
426 | "name": "webml",
427 | "avatar": "https://github.com/KeenS.png",
428 | "url": "https://github.com/KeenS/webml",
429 | "description": "A Standard ML Compiler for the Web",
430 | "language": "Rust",
431 | "languageColor": "#dea584",
432 | "stars": 212,
433 | "forks": 7,
434 | "currentPeriodStars": 31,
435 | "builtBy": [
436 | {
437 | "username": "KeenS",
438 | "href": "https://github.com/KeenS",
439 | "avatar": "https://avatars2.githubusercontent.com/u/4434568"
440 | }
441 | ]
442 | },
443 | {
444 | "author": "marcinguy",
445 | "name": "CVE-2020-8597",
446 | "avatar": "https://github.com/marcinguy.png",
447 | "url": "https://github.com/marcinguy/CVE-2020-8597",
448 | "description": "CVE-2020-8597",
449 | "language": "Python",
450 | "languageColor": "#3572A5",
451 | "stars": 38,
452 | "forks": 15,
453 | "currentPeriodStars": 8,
454 | "builtBy": [
455 | {
456 | "username": "marcinguy",
457 | "href": "https://github.com/marcinguy",
458 | "avatar": "https://avatars2.githubusercontent.com/u/20355405"
459 | }
460 | ]
461 | },
462 | {
463 | "author": "Netflix",
464 | "name": "dispatch",
465 | "avatar": "https://github.com/Netflix.png",
466 | "url": "https://github.com/Netflix/dispatch",
467 | "description": "All of the ad-hoc things you're doing to manage incidents today, done for you, and much more!",
468 | "language": "Python",
469 | "languageColor": "#3572A5",
470 | "stars": 1644,
471 | "forks": 90,
472 | "currentPeriodStars": 62,
473 | "builtBy": [
474 | {
475 | "username": "kevgliss",
476 | "href": "https://github.com/kevgliss",
477 | "avatar": "https://avatars2.githubusercontent.com/u/2262214"
478 | },
479 | {
480 | "username": "mvilanova",
481 | "href": "https://github.com/mvilanova",
482 | "avatar": "https://avatars0.githubusercontent.com/u/39573146"
483 | },
484 | {
485 | "username": "TheDahv",
486 | "href": "https://github.com/TheDahv",
487 | "avatar": "https://avatars3.githubusercontent.com/u/73363"
488 | },
489 | {
490 | "username": "daniel-gallagher",
491 | "href": "https://github.com/daniel-gallagher",
492 | "avatar": "https://avatars2.githubusercontent.com/u/17089890"
493 | },
494 | {
495 | "username": "abdullahselek",
496 | "href": "https://github.com/abdullahselek",
497 | "avatar": "https://avatars0.githubusercontent.com/u/5083377"
498 | }
499 | ]
500 | },
501 | {
502 | "author": "apache",
503 | "name": "incubator-shardingsphere",
504 | "avatar": "https://github.com/apache.png",
505 | "url": "https://github.com/apache/incubator-shardingsphere",
506 | "description": "Distributed database middleware",
507 | "language": "Java",
508 | "languageColor": "#b07219",
509 | "stars": 10036,
510 | "forks": 3417,
511 | "currentPeriodStars": 44,
512 | "builtBy": [
513 | {
514 | "username": "tristaZero",
515 | "href": "https://github.com/tristaZero",
516 | "avatar": "https://avatars2.githubusercontent.com/u/27757146"
517 | },
518 | {
519 | "username": "terrymanu",
520 | "href": "https://github.com/terrymanu",
521 | "avatar": "https://avatars0.githubusercontent.com/u/5516298"
522 | },
523 | {
524 | "username": "tuohai666",
525 | "href": "https://github.com/tuohai666",
526 | "avatar": "https://avatars2.githubusercontent.com/u/24643893"
527 | },
528 | {
529 | "username": "cherrylzhao",
530 | "href": "https://github.com/cherrylzhao",
531 | "avatar": "https://avatars0.githubusercontent.com/u/8317649"
532 | },
533 | {
534 | "username": "haocao",
535 | "href": "https://github.com/haocao",
536 | "avatar": "https://avatars0.githubusercontent.com/u/687732"
537 | }
538 | ]
539 | },
540 | {
541 | "author": "dotnet",
542 | "name": "aspnetcore",
543 | "avatar": "https://github.com/dotnet.png",
544 | "url": "https://github.com/dotnet/aspnetcore",
545 | "description": "ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.",
546 | "language": "C#",
547 | "languageColor": "#178600",
548 | "stars": 16378,
549 | "forks": 4367,
550 | "currentPeriodStars": 41,
551 | "builtBy": [
552 | {
553 | "username": "aspnetci",
554 | "href": "https://github.com/aspnetci",
555 | "avatar": "https://avatars3.githubusercontent.com/u/23037549"
556 | },
557 | {
558 | "username": "pranavkm",
559 | "href": "https://github.com/pranavkm",
560 | "avatar": "https://avatars1.githubusercontent.com/u/174281"
561 | },
562 | {
563 | "username": "SteveSandersonMS",
564 | "href": "https://github.com/SteveSandersonMS",
565 | "avatar": "https://avatars2.githubusercontent.com/u/1101362"
566 | },
567 | {
568 | "username": "Tratcher",
569 | "href": "https://github.com/Tratcher",
570 | "avatar": "https://avatars1.githubusercontent.com/u/1821173"
571 | },
572 | {
573 | "username": "rynowak",
574 | "href": "https://github.com/rynowak",
575 | "avatar": "https://avatars3.githubusercontent.com/u/1430011"
576 | }
577 | ]
578 | },
579 | {
580 | "author": "HospitalRun",
581 | "name": "hospitalrun-frontend",
582 | "avatar": "https://github.com/HospitalRun.png",
583 | "url": "https://github.com/HospitalRun/hospitalrun-frontend",
584 | "description": "Frontend for HospitalRun",
585 | "language": "TypeScript",
586 | "languageColor": "#2b7489",
587 | "stars": 5080,
588 | "forks": 1555,
589 | "currentPeriodStars": 39,
590 | "builtBy": [
591 | {
592 | "username": "jkleinsc",
593 | "href": "https://github.com/jkleinsc",
594 | "avatar": "https://avatars2.githubusercontent.com/u/609052"
595 | },
596 | {
597 | "username": "tangollama",
598 | "href": "https://github.com/tangollama",
599 | "avatar": "https://avatars3.githubusercontent.com/u/929261"
600 | },
601 | {
602 | "username": "jglovier",
603 | "href": "https://github.com/jglovier",
604 | "avatar": "https://avatars2.githubusercontent.com/u/1319791"
605 | },
606 | {
607 | "username": "tehKapa",
608 | "href": "https://github.com/tehKapa",
609 | "avatar": "https://avatars0.githubusercontent.com/u/6388707"
610 | },
611 | {
612 | "username": "hospitalrunbot",
613 | "href": "https://github.com/hospitalrunbot",
614 | "avatar": "https://avatars3.githubusercontent.com/u/22404737"
615 | }
616 | ]
617 | },
618 | {
619 | "author": "CyC2018",
620 | "name": "CS-Notes",
621 | "avatar": "https://github.com/CyC2018.png",
622 | "url": "https://github.com/CyC2018/CS-Notes",
623 | "description": "📚 技术面试必备基础知识、Leetcode、计算机操作系统、计算机网络、系统设计、Java、Python、C++",
624 | "language": "Java",
625 | "languageColor": "#b07219",
626 | "stars": 93554,
627 | "forks": 30326,
628 | "currentPeriodStars": 280,
629 | "builtBy": [
630 | {
631 | "username": "CyC2018",
632 | "href": "https://github.com/CyC2018",
633 | "avatar": "https://avatars1.githubusercontent.com/u/36260787"
634 | },
635 | {
636 | "username": "kwongtailau",
637 | "href": "https://github.com/kwongtailau",
638 | "avatar": "https://avatars1.githubusercontent.com/u/22954582"
639 | },
640 | {
641 | "username": "linehk",
642 | "href": "https://github.com/linehk",
643 | "avatar": "https://avatars0.githubusercontent.com/u/8375793"
644 | },
645 | {
646 | "username": "crossoverJie",
647 | "href": "https://github.com/crossoverJie",
648 | "avatar": "https://avatars0.githubusercontent.com/u/15684156"
649 | },
650 | {
651 | "username": "Lisanaaa",
652 | "href": "https://github.com/Lisanaaa",
653 | "avatar": "https://avatars1.githubusercontent.com/u/28261876"
654 | }
655 | ]
656 | },
657 | {
658 | "author": "3b1b",
659 | "name": "manim",
660 | "avatar": "https://github.com/3b1b.png",
661 | "url": "https://github.com/3b1b/manim",
662 | "description": "Animation engine for explanatory math videos",
663 | "language": "Python",
664 | "languageColor": "#3572A5",
665 | "stars": 17548,
666 | "forks": 2108,
667 | "currentPeriodStars": 70,
668 | "builtBy": [
669 | {
670 | "username": "3b1b",
671 | "href": "https://github.com/3b1b",
672 | "avatar": "https://avatars2.githubusercontent.com/u/11601040"
673 | },
674 | {
675 | "username": "bhbr",
676 | "href": "https://github.com/bhbr",
677 | "avatar": "https://avatars2.githubusercontent.com/u/13440601"
678 | },
679 | {
680 | "username": "eulertour",
681 | "href": "https://github.com/eulertour",
682 | "avatar": "https://avatars1.githubusercontent.com/u/43117506"
683 | },
684 | {
685 | "username": "Sridhar3b1b",
686 | "href": "https://github.com/Sridhar3b1b",
687 | "avatar": "https://avatars1.githubusercontent.com/u/35234358"
688 | },
689 | {
690 | "username": "mirefek",
691 | "href": "https://github.com/mirefek",
692 | "avatar": "https://avatars3.githubusercontent.com/u/25885450"
693 | }
694 | ]
695 | },
696 | {
697 | "author": "UniversalDataTool",
698 | "name": "universal-data-tool",
699 | "avatar": "https://github.com/UniversalDataTool.png",
700 | "url": "https://github.com/UniversalDataTool/universal-data-tool",
701 | "description": "Collaborate & label any type of data, images, text, or documents, in an easy web interface or desktop app.",
702 | "language": "JavaScript",
703 | "languageColor": "#f1e05a",
704 | "stars": 281,
705 | "forks": 12,
706 | "currentPeriodStars": 41,
707 | "builtBy": [
708 | {
709 | "username": "seveibar",
710 | "href": "https://github.com/seveibar",
711 | "avatar": "https://avatars3.githubusercontent.com/u/1910070"
712 | },
713 | {
714 | "username": "puskuruk",
715 | "href": "https://github.com/puskuruk",
716 | "avatar": "https://avatars2.githubusercontent.com/u/22892227"
717 | }
718 | ]
719 | }
720 | ]
721 |
--------------------------------------------------------------------------------
/cypress/integration/dark-mode.js:
--------------------------------------------------------------------------------
1 | describe('Dark Mode', () => {
2 | it('set local storage preferDarkMode to true if in dark mode', () => {
3 | cy.fetchReposAndWait({ darkMode: true });
4 | cy.window().its('localStorage.preferDarkMode').should('eq', 'true');
5 | cy.findByLabelText('Sun Icon').should('exist');
6 | cy.findByLabelText('Moon Icon').should('not.exist');
7 | });
8 |
9 | it('set local storage preferDarkMode to false if in light mode', () => {
10 | cy.fetchReposAndWait({ darkMode: false });
11 | cy.window().its('localStorage.preferDarkMode').should('eq', 'false');
12 | cy.findByLabelText('Moon Icon').should('exist');
13 | cy.findByLabelText('Sun Icon').should('not.exist');
14 | });
15 |
16 | it('click on icon should change mode and local storage value', () => {
17 | cy.fetchReposAndWait({ darkMode: true });
18 | cy.findByLabelText('Sun Icon').click();
19 | cy.findByLabelText('Moon Icon').should('exist');
20 | cy.findByLabelText('Sun Icon').should('not.exist');
21 | cy.getLocalStorage('preferDarkMode').should('eq', false);
22 | cy.findByLabelText('Moon Icon').click();
23 | cy.findByLabelText('Moon Icon').should('not.exist');
24 | cy.findByLabelText('Sun Icon').should('exist');
25 | cy.getLocalStorage('preferDarkMode').should('eq', true);
26 | });
27 | });
28 |
--------------------------------------------------------------------------------
/cypress/integration/empty-state.js:
--------------------------------------------------------------------------------
1 | describe('Empty state', () => {
2 | it('shows empty state when response is empty', () => {
3 | cy.fetchReposAndWait({ response: [] });
4 | cy.findByText('Trending Repositories').should('not.exist');
5 | cy.findByTestId('repo-card').should('not.exist');
6 | cy.findByTestId('empty-state').should('exist');
7 | });
8 |
9 | it('does not show empty state when response is normal', () => {
10 | cy.fetchReposAndWait();
11 | cy.findByText('empty-state').should('not.exist');
12 | });
13 | });
14 |
--------------------------------------------------------------------------------
/cypress/integration/error-state.js:
--------------------------------------------------------------------------------
1 | describe('Error state', () => {
2 | it('shows error banner when response is not 200', () => {
3 | cy.errorFetchReposAndWait();
4 | cy.findByTestId('empty-state').should('exist');
5 | cy.findByTestId('network-error-banner').should('exist');
6 | cy.findByLabelText('Close').click();
7 | cy.findByTestId('network-error-banner').should('not.exist');
8 | });
9 |
10 | it('should reload when click retry', () => {
11 | cy.errorFetchReposAndWait();
12 | cy.findByTestId('empty-state').should('exist');
13 | cy.findByTestId('network-error-banner').should('exist');
14 | cy.fetchRepos();
15 | cy.findByText('Retry').click();
16 | cy.findByTestId('network-error-banner').should('not.exist');
17 | cy.shouldHaveRepoCards(25);
18 | });
19 |
20 | it('should show error banner when repo was already loaded', () => {
21 | cy.fetchRepos({ status: 500 });
22 | cy.seedLocalStorage();
23 | cy.visit('/');
24 | cy.findByTestId('last-updated-time').click();
25 | cy.waitAllErrors();
26 | cy.findByTestId('network-error-banner').should('exist');
27 | cy.shouldHaveRepoCards(25);
28 | });
29 |
30 | it('does not show error banner when response is normal', () => {
31 | cy.fetchReposAndWait();
32 | cy.findByTestId('network-error-banner').should('not.exist');
33 | });
34 | });
35 |
--------------------------------------------------------------------------------
/cypress/integration/feeling-lucky.js:
--------------------------------------------------------------------------------
1 | describe('I’m Feeling Lucky', () => {
2 | it('should have a lucky repo', () => {
3 | cy.fetchReposAndWait();
4 |
5 | cy.fixture('trending').then((json) => {
6 | const names = json.map((repo) => repo.name);
7 | cy.findByText('I’m Feeling Lucky').should('exist');
8 | cy.findByTestId('random-repo-list')
9 | .findAllByTestId('repo-card')
10 | .should('have.length', 1);
11 | cy.findByTestId('random-repo-list')
12 | .findByTestId('name')
13 | .invoke('text')
14 | .should('be.oneOf', names);
15 | cy.findByLabelText('Random Pick Button').click();
16 | cy.findByTestId('random-repo-list')
17 | .findAllByTestId('repo-card')
18 | .should('have.length', 1);
19 | cy.findByTestId('random-repo-list')
20 | .findByTestId('name')
21 | .invoke('text')
22 | .should('be.oneOf', names);
23 | });
24 | });
25 |
26 | it('reload should update the picked item', () => {
27 | cy.fetchReposAndWait();
28 |
29 | cy.fixture('trending').then((json) => {
30 | const names = json.map((repo) => repo.name);
31 | cy.findByTestId('random-repo-list')
32 | .findByTestId('name')
33 | .invoke('text')
34 | .should('be.oneOf', names);
35 | });
36 |
37 | cy.fixture('trending-2').then((json) => {
38 | const names = json.map((repo) => repo.name);
39 | cy.route({
40 | method: 'GET',
41 | url: 'https://ghapi.huchen.dev/repositories?since=daily',
42 | response: 'fixture:trending-2',
43 | }).as('fetchRepos');
44 | cy.findByTestId('last-updated-time').click();
45 | cy.waitResponse();
46 | cy.findByTestId('random-repo-list')
47 | .findByTestId('name')
48 | .invoke('text')
49 | .should('be.oneOf', names);
50 | });
51 | });
52 | });
53 |
--------------------------------------------------------------------------------
/cypress/integration/load-repositories.js:
--------------------------------------------------------------------------------
1 | describe('Load Repositories', () => {
2 | it('load repo cards', () => {
3 | cy.fetchReposAndWait();
4 | cy.findByText('Trending Repositories').should('exist');
5 | cy.shouldHaveRepoCards(25);
6 | });
7 |
8 | it('shows loading placeholder while loading', () => {
9 | cy.fetchRepos({ delay: 100 });
10 | cy.visit('/');
11 | cy.findAllByTestId('loading-card').should('have.length', 10);
12 | cy.wait('@fetchRepos');
13 | cy.findByTestId('loading-card').should('not.exist');
14 | cy.shouldHaveRepoCards(25);
15 | });
16 |
17 | it('should set local storage values', () => {
18 | const now = new Date('2020-01-01T08:30:00').getTime();
19 | cy.clock(now);
20 | cy.fetchReposAndWait();
21 | cy.getLocalStorage('selectedLanguage').should('eq', '__ALL__');
22 | cy.getLocalStorage('selectedPeriod').should('eq', 'daily');
23 | cy.getLocalStorage('selectedSpokenLanguage').should('eq', '__ALL__');
24 | cy.getLocalStorage('schemaVersion').should('eq', '2');
25 | cy.getLocalStorage('lastUpdatedTime').should('eq', now);
26 | cy.fixture('trending').then((json) => {
27 | cy.getLocalStorage('repositories').should('deep.eq', json);
28 | });
29 | });
30 |
31 | it('should not fetch if repos is cached in local storage', () => {
32 | cy.server({ enable: false });
33 | cy.setLocalStorage('schemaVersion', '2');
34 | cy.fixture('trending').then((json) => {
35 | cy.setLocalStorage('repositories', json);
36 | });
37 | cy.visit('/');
38 | cy.findByTestId('loading-card').should('not.exist');
39 | cy.shouldHaveRepoCards(25);
40 | cy.shouldHaveFirstCardContains('COVID-19 Italia - Monitoraggio situazione');
41 | });
42 |
43 | it('should show last updated time', () => {
44 | cy.seedLocalStorage();
45 | cy.visit('/');
46 | cy.findByText('10 minutes ago').should('exist');
47 | });
48 |
49 | it('click last updated time should refetch repositories', () => {
50 | const fixtureTime = new Date('2020-01-01T08:20:00').getTime();
51 | cy.seedLocalStorage({
52 | lastUpdatedTime: fixtureTime,
53 | });
54 | cy.server();
55 | cy.route({
56 | method: 'GET',
57 | url: 'https://ghapi.huchen.dev/repositories?since=daily',
58 | response: 'fixture:trending-2',
59 | }).as('fetchRepos');
60 | cy.visit('/');
61 | cy.findByTestId('last-updated-time').click();
62 | cy.waitResponse();
63 | cy.getLocalStorage('lastUpdatedTime').should('be.greaterThan', fixtureTime);
64 | cy.fixture('trending-2').then((json) => {
65 | cy.getLocalStorage('repositories').should('deep.eq', json);
66 | });
67 | cy.shouldHaveFirstCardContains(
68 | 'An operating system designed for hosting containers'
69 | );
70 | });
71 |
72 | it('clears localStorage if schema version is different', () => {
73 | const now = new Date('2020-01-01T08:30:00').getTime();
74 | cy.clock(now);
75 | cy.seedLocalStorage({
76 | lastUpdatedTime: new Date('2020-01-01T08:20:00').getTime(),
77 | schemaVersion: '1',
78 | repositories: 'trending-2',
79 | selectedLanguage: 'javascript',
80 | selectedPeriod: 'weekly',
81 | selectedSpokenLanguage: 'en',
82 | });
83 | cy.fetchReposAndWait();
84 | cy.fixture('trending').then((json) => {
85 | cy.getLocalStorage('repositories').should('deep.eq', json);
86 | });
87 | cy.getLocalStorage('selectedLanguage').should('eq', '__ALL__');
88 | cy.getLocalStorage('selectedPeriod').should('eq', 'daily');
89 | cy.getLocalStorage('selectedSpokenLanguage').should('eq', '__ALL__');
90 | cy.getLocalStorage('schemaVersion').should('eq', '2');
91 | cy.getLocalStorage('lastUpdatedTime').should('eq', now);
92 | });
93 | });
94 |
--------------------------------------------------------------------------------
/cypress/integration/scroll-icon.js:
--------------------------------------------------------------------------------
1 | describe('Scroll Icon', () => {
2 | it('should scroll to top', () => {
3 | cy.seedLocalStorage();
4 | cy.visit('/');
5 | cy.findByLabelText('Scroll to Top Button').should('not.be.visible');
6 | cy.scrollTo(0, 300);
7 | cy.window().its('pageYOffset').should('eq', 300);
8 | cy.findByLabelText('Scroll to Top Button').should('be.visible');
9 | cy.findByLabelText('Scroll to Top Button').click();
10 | cy.window().its('pageYOffset').should('eq', 0);
11 | cy.findByLabelText('Scroll to Top Button').should('not.be.visible');
12 | });
13 | });
14 |
--------------------------------------------------------------------------------
/cypress/integration/selectors.js:
--------------------------------------------------------------------------------
1 | describe('Selectors', () => {
2 | it('should fetch correct endpoint when change language selector', () => {
3 | cy.fetchReposAndWait();
4 | cy.findByTestId('top-bar').findByText('All languages').should('be.visible');
5 | cy.findByTestId('top-bar')
6 | .findByText('Trending today')
7 | .should('be.visible');
8 |
9 | cy.findByTestId('language-selector').click();
10 | cy.route({
11 | method: 'GET',
12 | url:
13 | 'https://ghapi.huchen.dev/repositories?language=javascript&since=daily',
14 | response: 'fixture:javascript',
15 | delay: 100,
16 | }).as('fetchRepos');
17 | cy.findByTestId('language-selector').findByText('JavaScript').click();
18 | cy.findAllByTestId('loading-card').should('have.length', 10);
19 | cy.wait('@fetchRepos');
20 | cy.findByTestId('loading-card').should('not.exist');
21 | cy.shouldHaveRepoCards(25);
22 | cy.getLocalStorage('selectedLanguage').should('eq', 'javascript');
23 | cy.fixture('javascript').then((json) => {
24 | cy.getLocalStorage('repositories').should('deep.eq', json);
25 | });
26 | cy.findByTestId('top-bar').findByText('JavaScript').should('be.visible');
27 | cy.findByTestId('top-bar')
28 | .findByText('Trending today')
29 | .should('be.visible');
30 |
31 | cy.findByTestId('period-selector').click();
32 | cy.route({
33 | method: 'GET',
34 | url:
35 | 'https://ghapi.huchen.dev/repositories?language=javascript&since=monthly',
36 | response: 'fixture:javascript-monthly',
37 | delay: 100,
38 | }).as('fetchRepos');
39 | cy.findByTestId('period-selector')
40 | .findByText('Trending this month')
41 | .click();
42 | cy.findAllByTestId('loading-card').should('have.length', 10);
43 | cy.wait('@fetchRepos');
44 | cy.findByTestId('loading-card').should('not.exist');
45 | cy.shouldHaveRepoCards(25);
46 | cy.getLocalStorage('selectedPeriod').should('eq', 'monthly');
47 | cy.fixture('javascript-monthly').then((json) => {
48 | cy.getLocalStorage('repositories').should('deep.eq', json);
49 | });
50 | cy.findByTestId('top-bar').findByText('JavaScript').should('be.visible');
51 | cy.findByTestId('top-bar')
52 | .findByText('Trending this month')
53 | .should('be.visible');
54 |
55 | // should load from cache
56 | cy.findByTestId('period-selector').click();
57 | cy.findByTestId('period-selector').findByText('Trending today').click();
58 | cy.findByTestId('loading-card').should('not.exist');
59 | cy.shouldHaveRepoCards(25);
60 | cy.fixture('javascript').then((json) => {
61 | cy.getLocalStorage('repositories').should('deep.eq', json);
62 | });
63 | });
64 |
65 | it('should fetch correct endpoint when change spoken language selector', () => {
66 | cy.fetchReposAndWait();
67 | cy.findByTestId('top-bar')
68 | .findByText('All spoken languages')
69 | .should('be.visible');
70 | cy.findByTestId('top-bar')
71 | .findByText('Trending today')
72 | .should('be.visible');
73 |
74 | cy.findByTestId('spoken-language-selector').click();
75 | cy.route({
76 | method: 'GET',
77 | url:
78 | 'https://ghapi.huchen.dev/repositories?since=daily&spoken_language_code=en',
79 | response: 'fixture:english',
80 | delay: 100,
81 | }).as('fetchRepos');
82 | cy.findByTestId('spoken-language-selector').findByText('English').click();
83 | cy.findAllByTestId('loading-card').should('have.length', 10);
84 | cy.wait('@fetchRepos');
85 | cy.findByTestId('loading-card').should('not.exist');
86 | cy.shouldHaveRepoCards(25);
87 | cy.getLocalStorage('selectedSpokenLanguage').should('eq', 'en');
88 | cy.fixture('english').then((json) => {
89 | cy.getLocalStorage('repositories').should('deep.eq', json);
90 | });
91 | cy.findByTestId('top-bar').findByText('English').should('be.visible');
92 | cy.findByTestId('top-bar')
93 | .findByText('Trending today')
94 | .should('be.visible');
95 |
96 | cy.findByTestId('period-selector').click();
97 | cy.route({
98 | method: 'GET',
99 | url:
100 | 'https://ghapi.huchen.dev/repositories?since=monthly&spoken_language_code=en',
101 | response: 'fixture:english-monthly',
102 | delay: 100,
103 | }).as('fetchRepos');
104 | cy.findByTestId('period-selector')
105 | .findByText('Trending this month')
106 | .click();
107 | cy.findAllByTestId('loading-card').should('have.length', 10);
108 | cy.wait('@fetchRepos');
109 | cy.findByTestId('loading-card').should('not.exist');
110 | cy.shouldHaveRepoCards(25);
111 | cy.getLocalStorage('selectedPeriod').should('eq', 'monthly');
112 | cy.fixture('english-monthly').then((json) => {
113 | cy.getLocalStorage('repositories').should('deep.eq', json);
114 | });
115 | cy.findByTestId('top-bar').findByText('English').should('be.visible');
116 | cy.findByTestId('top-bar')
117 | .findByText('Trending this month')
118 | .should('be.visible');
119 | });
120 |
121 | it('should have selectors selected correctly when localStorage was set', () => {
122 | cy.seedLocalStorage({
123 | selectedPeriod: 'monthly',
124 | selectedLanguage: 'javascript',
125 | selectedSpokenLanguage: 'en',
126 | repositories: 'javascript-monthly',
127 | });
128 | cy.visit('/');
129 | cy.findByTestId('top-bar').findByText('JavaScript').should('be.visible');
130 | cy.findByTestId('top-bar').findByText('English').should('be.visible');
131 | cy.findByTestId('top-bar')
132 | .findByText('Trending this month')
133 | .should('be.visible');
134 | });
135 |
136 | it('should have default selectors selected when local storage was not set', () => {
137 | cy.fetchReposAndWait();
138 | cy.findByTestId('top-bar').findByText('All languages').should('be.visible');
139 | cy.findByTestId('top-bar')
140 | .findByText('All spoken languages')
141 | .should('be.visible');
142 | cy.findByTestId('top-bar')
143 | .findByText('Trending today')
144 | .should('be.visible');
145 | });
146 | });
147 |
--------------------------------------------------------------------------------
/cypress/plugins/index.js:
--------------------------------------------------------------------------------
1 | ///
62 | This may be a few minutes. Now would be a great time to write that 63 | novel you have always been talking about. 64 |
65 |