Skip to content

Commit

Permalink
Merge pull request #40 from oslabs-beta/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
johnwdunn20 authored Dec 15, 2023
2 parents 01e6f6c + 3e271dc commit 4600fc6
Show file tree
Hide file tree
Showing 129 changed files with 58,920 additions and 1 deletion.
Binary file added .DS_Store
Binary file not shown.
58 changes: 58 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Run Tests and Build
on:
pull_request:
branches:
- main
- dev
push:
branches:
- main
- dev
jobs:
unit-testing-extension:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use Node.js 18
uses: actions/setup-node@v4
with:
node-version: 18
cache: 'npm'
- name: Install Extension dependencies
run: |
cd extension
npm ci
- name: Build Extension
run: |
cd extension
npm run build
- name: Test Extension
run: |
cd extension
npm test
unit-testing-package:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use Node.js 18
uses: actions/setup-node@v4
with:
node-version: 18
cache: 'npm'
- name: Install Package dependencies
run: |
cd package
npm ci
- name: Install linux handler for github actions
run: |
cd package
npm i @rollup/rollup-linux-x64-gnu
- name: Build Package
run: |
cd package
npm run build
- name: Test Package
run: |
cd package
npm test
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules/
dist
154 changes: 153 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,153 @@
# react-query-rewind
<a id="readme-top"></a>

<p align="center">
<img src="./extension/public/icon.png" alt="Logo" width="250"/>
</p>

# Technologies

[![JavaScript](https://img.shields.io/badge/javascript-%23323330.svg?style=for-the-badge&logo=javascript&logoColor=%23F7DF1E)](https://www.javascript.com/)
[![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?style=for-the-badge&logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
[![React](https://img.shields.io/badge/react-%2320232a.svg?style=for-the-badge&logo=react&logoColor=%2361DAFB)](https://reactjs.org/)
[![HTML5](https://img.shields.io/badge/html5-%23E34F26.svg?style=for-the-badge&logo=html5&logoColor=white)](https://html.com/html5/)
[![Webpack](https://img.shields.io/badge/webpack-%238DD6F9.svg?style=for-the-badge&logo=webpack&logoColor=black)](https://webpack.js.org/)
[![D3](https://img.shields.io/badge/d3%20js-F9A03C?style=for-the-badge&logo=d3.js&logoColor=white)](https://d3js.org/)
[![ESLint](https://img.shields.io/badge/eslint-3A33D1?style=for-the-badge&logo=eslint&logoColor=white)](https://eslint.org/)
[![Material UI](https://img.shields.io/badge/Material%20UI-007FFF?style=for-the-badge&logo=mui&logoColor=white)](https://mui.com/)
[![Jest](https://img.shields.io/badge/Jest-C21325?style=for-the-badge&logo=jest&logoColor=white)](https://jestjs.io/)
[![Babel](https://img.shields.io/badge/Babel-F9DC3E?style=for-the-badge&logo=babel&logoColor=white)](https://babeljs.io/)

# Overview

React Query Rewind introduces a powerful DevTool extension designed to work in conjunction with React Query's built-in DevTools in order to optimize time-traveling through state changes in an application. This open-source extension is tailored to enhance the debugging experience for React Query users, allowing them to explore state changes and component relationships with ease.

# Getting Started

## Prerequisites

1. React Query installed and in use in your application.

2. Install RQRewind Chrome Extension.

<!-- _link / picture of Extension in Chrome Store_ -->

## Installation

1. Download npm package into your application.

```sh
npm i react-query-rewind
```

2. Import the ReactQueryRewind component into the root of your applicaiton.

_picture of importing the component_

```javascript
import ReactQueryRewind from 'react-query-rewind';
```

3. Place ReactQueryRewind next to the root of your application inside the QueryClientProvider component.

```javascript
ReactDOM.createRoot(document.getElementById('root')!).render(
<QueryClientProvider client={queryClient}>
<App />
<ReactQueryRewind />
</QueryClientProvider>
);
```

4. Open the Chrome DevTool Extension and start coding!

<p align="left">
<img src="./assets/chrome-devtool.png" alt="Component Placement" width="600"/>
</p>

# Features

- <b>Query States: </b>Upon opening RQRewind in Chrome Dev Tools, you will see the Queries tab open with a drop down menu listing the query keys of all the incoming queries. Select the queries that you want to monitor, make changes on the web app, and the changes of query states will be logged as reflected by the growing number above the play bar. Use the play bar to navigate to a particular state snapshot that you would like to inspect.

<p align="center"><img src="./assets/query-states.gif" width='800' style="margin-top: 1em; margin-bottom: 1em;"></p>

- <b>State Diff: </b>Toggle on the Diff button to see state changes between each snapshot highlighted. Turn on the switch on top of the page to show only parts of the state that are changed.

<p align="center"><img src="./assets/state-diff.gif" width='800' style="margin-top: 1em; margin-bottom: 1em;"></p>

- <b>Live UI Change: </b>As you review the state change history, there is also the option to turn on the time travel mode by clicking on the clock icon button. Under time travel mode, when visiting a logged state snapshot on RQRewindl, the UI of the app will change accordingly. Turn off time travel mode for RQRewind to continue logging future state changes.

<p align="center"><img src="./assets/UI-change.gif" width='800' style="margin-top: 1em; margin-bottom: 1em;"></p>

- <b>Component Tree: </b> Click on the Component Tree tab and turn on the Start Profiling switch. Click on any component on the app, and view the component tree that is rendered on the dev tools panel.

<p align="center"><img src="./assets/component-tree.gif" width='800' style="margin-top: 1em; margin-bottom: 1em;"></p>

# Contributing

React Query Rewind values the strength of community involvement. If you're enthusiastic about React Query, time-traveling state, or improving debugging experiences, your contributions are highly appreciated. Whether it's code enhancements, documentation improvements, or innovative feature suggestions, your engagement can play a pivotal role in shaping the future of React Query Rewind. If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement".
Don't forget to give the project a star! Thanks again!
1. Fork the Project
2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)
3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)
4. Push to the Branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request
# Contact Information
Austin Cavanagh - [GitHub](https://github.com/austin-cavanagh) - [LinkedIn](https://www.linkedin.com/in/austincavanagh/) - austin.cavanagh.cs@gmail.com
Emma Teering - [GitHub](https://github.com/eteering) - [LinkedIn](https://www.linkedin.com/in/emma-teering/) - teeringe@gmail.com
John Dunn - [GitHub](https://github.com/johnwdunn20) - [LinkedIn](https://www.linkedin.com/in/johnwdunn/) - johnwdunn20@gmail.com
Rui Fan - [GitHub](https://github.com/ruifan-IU) - [LinkedIn](https://www.linkedin.com/in/rui-fan-868231299/) - rfan1986@gmail.com
# Links
[![Medium](https://img.shields.io/badge/Medium-12100E?style=for-the-badge&logo=medium&logoColor=white)](https://medium.com/@teeringe/react-query-rewind-time-travel-debugging-made-simple-46aaeeafd497)
[![LinkedIn](https://img.shields.io/badge/LinkedIn-0077B5?style=for-the-badge&logo=linkedin&logoColor=white)](https://www.linkedin.com/company/react-query-rewind/)
Project Link: [React Query Rewind](https://github.com/oslabs-beta/react-query-rewind-chrome)
# License
_MIT Link_
<p align="right">(<a href="#readme-top">back to top</a>)</p>
<!-- TABLE OF CONTENTS -->
<!-- <details>
<summary>Table of Contents</summary>
<ol>
<li>
<a href="#about-the-project">About The Project</a>
<ul>
<li><a href="#built-with">Built With</a></li>
</ul>
</li>
<li>
<a href="#getting-started">Getting Started</a>
<ul>
<li><a href="#prerequisites">Prerequisites</a></li>
<li><a href="#installation">Installation</a></li>
</ul>
</li>
<li><a href="#usage">Usage</a></li>
<li><a href="#roadmap">Roadmap</a></li>
<li><a href="#contributing">Contributing</a></li>
<li><a href="#license">License</a></li>
<li><a href="#contact">Contact</a></li>
<li><a href="#acknowledgments">Acknowledgments</a></li>
</ol>
</details> -->
<!-- <p align="right">(<a href="#readme-top">back to top</a>)</p> -->
<!-- <a name="website" href="ARE WE GONNA HAVE A WEBSITE">Website</a> -->
<!-- [![Contributors](https://img.shields.io/github/contributors/oslabs-beta/react-query-rewind-chrome.svg?style=for-the-badge)](https://github.com/oslabs-beta/react-query-rewind-chrome/graphs/contributors)
[![Forks](https://img.shields.io/github/forks/oslabs-beta/react-query-rewind-chrome.svg?style=for-the-badge)](https://github.com/oslabs-beta/react-query-rewind-chrome/forks)
[![Stargazers](https://img.shields.io/github/stars/oslabs-beta/react-query-rewind-chrome.svg?style=for-the-badge)](https://github.com/oslabs-beta/react-query-rewind-chrome/stargazers)
[![Issues](https://img.shields.io/github/issues/oslabs-beta/react-query-rewind-chrome.svg?style=for-the-badge)](https://github.com/oslabs-beta/react-query-rewind-chrome/issues)
[![MIT License](https://img.shields.io/github/license/oslabs-beta/react-query-rewind-chrome.svg?style=for-the-badge)](https://github.com/oslabs-beta/react-query-rewind-chrome/blob/main/LICENSE) -->
Binary file added assets/UI-change.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/chrome-devtool.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/component-tree.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/query-states.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/state-diff.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added extension/.DS_Store
Binary file not shown.
2 changes: 2 additions & 0 deletions extension/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
build/
21 changes: 21 additions & 0 deletions extension/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2023 OSLabs Beta

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

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

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Empty file added extension/README.md
Empty file.
13 changes: 13 additions & 0 deletions extension/__tests__/JsonFormatter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react';
import { render } from '@testing-library/react';
import JsonFormatter from '../src/components/JsonFormatter';

describe('JsonFormatter component', () => {
it('renders without crashing', () => {
render(<JsonFormatter
key={1}
queryKey={'[posts-one]'}
jsonData={{val: 'test', arr: [1,2,3]}}
/>);
});
});
56 changes: 56 additions & 0 deletions extension/__tests__/saveSelectedQueryKeys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import saveSelectedQueryKeys from "../src/functions/saveSelectedQueryKeys";

// Based on: https://elvisciotti.medium.com/create-a-working-chrome-storage-your-chrome-edge-browser-extension-during-testing-with-jest-071d69fcf8a1

// mock chrome extension get and set functions
let localStorage: any = {
thisSessionsQueries: undefined,
selectedQueries: undefined
};

global.chrome = {
storage: {
local: {
clear: () => {
localStorage = {
thisSessionsQueries: undefined,
selectedQueries: undefined
}
},
// set takes in obj with key thisSessionsQueries or selectedQueries and the value that will be stored
set: (newValue: any) => {
localStorage = { ...localStorage, ...newValue };
},
// get returns a promise that resolves to an object with key value pairs
get: (key: any) => {
return Promise.resolve({ [key]: localStorage[key] });
}
},
}
} as unknown as typeof chrome;


describe('saveSelectedQueryKeys basic tests', () => {
// clear info stored in mock function calls and their arrays
beforeEach(() => {
chrome.storage.local.clear();
});

it('should set storage to empty array when queries is an empty array and no previous data is stored', async () => {
await saveSelectedQueryKeys([]);

expect(localStorage).toEqual({
thisSessionsQueries: [],
selectedQueries: []
});
})

it('should set storage to when passed an array with an queryKey in it', async () => {
await saveSelectedQueryKeys(['[queryKeyTest]'])

expect(localStorage).toEqual({
thisSessionsQueries: ['[queryKeyTest]'],
selectedQueries: ['[queryKeyTest]']
});
})
});
7 changes: 7 additions & 0 deletions extension/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
presets:[
"@babel/preset-env",
"@babel/preset-react",
'@babel/preset-typescript'
]
}
43 changes: 43 additions & 0 deletions extension/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
module.exports = {
// Specifies the Jest preset - "ts-jest" is used for TypeScript
preset: 'ts-jest',

// Automatically clear mock calls and instances between every test
clearMocks: true,

// The directory where Jest should output its coverage files
coverageDirectory: "tests/coverage",

// A set of global variables that need to be available in all test environments
globals: {
'ts-jest': {
// Tells ts-jest to use the isolatedModules mode
isolatedModules: true,
},
},

// The test environment that will be used for testing
testEnvironment: "jsdom",

// An array of regexp pattern strings that are matched against all test paths
// This is used to skip test files that are not necessary
testPathIgnorePatterns: [
"/node_modules/"
],

// A map from regular expressions to module names or to arrays of module names
// that allow to stub out resources, like images or styles with a single module
moduleNameMapper: {
'\\.(css|less|scss|sass)$': 'identity-obj-proxy'
},

// This configuration is necessary to transform JSX into JavaScript using Babel
transform: {
'^.+\\.(js|jsx|ts|tsx)$': 'babel-jest',
'^.+\\.css$': '<rootDir>/jestConfig/cssTransform.js',
'^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '<rootDir>/jestConfig/fileTransform.js'
},

// Indicates whether each individual test should be reported during the run
verbose: true,
};
10 changes: 10 additions & 0 deletions extension/jestConfig/cssTransform.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// cssTransform.js
module.exports = {
process() {
return 'module.exports = {};';
},
getCacheKey() {
// The output is always the same.
return 'cssTransform';
},
};
9 changes: 9 additions & 0 deletions extension/jestConfig/fileTransform.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// fileTransform.js
const path = require('path');

// Importing images is a way to include them in your browser bundle, but they are not valid JavaScript. One way of handling it in Jest is to replace the imported value with its filename.
module.exports = {
process(src, filename) {
return `module.exports = ${JSON.stringify(path.basename(filename))};`;
},
};
Loading

0 comments on commit 4600fc6

Please sign in to comment.