Skip to content

Commit

Permalink
Add the ability to delete cache values via UI (#21)
Browse files Browse the repository at this point in the history
ballercat authored Jul 10, 2023
1 parent 0a8b285 commit 3b372a1
Showing 65 changed files with 820 additions and 90 deletions.
20 changes: 7 additions & 13 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
name: Quality Checks

on:
pull_request:
types: [opened]
push:
branches:
- '**'
- 'main'
pull_request:

jobs:
test:
@@ -18,20 +16,16 @@ jobs:
node-version: 16.x.x
- run: yarn
- run: yarn test
- name: cypress
uses: cypress-io/github-action@v5
with:
start: npm run e2e
command: npm run cy-ci
- name: SonarCloud Scan
uses: SonarSource/sonarcloud-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
cypress:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: cypress
uses: cypress-io/github-action@v5
with:
start: npm run e2e-dev
command: npm run cy-ci
- uses: actions/upload-artifact@v3
with:
name: cypress-videos
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
.vscode
node_modules
coverage
coverage-cypress
cypress/videos
.DS_Store
*.log
dist
Empty file added .jambox/.gitkeep
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## 0.0.19 - Cache view updates

- feat: delete cache from UI
- feat: new json editor
- feat: add /api/cache POST api
- fix: collect coverage on cypress tests via c8
- fix: properly run github actions

## 0.0.18 - Update UI: Add cache view, sidenav

- feature: cache view
7 changes: 7 additions & 0 deletions cypress.config.js
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ module.exports = defineConfig({
viewportHeight: 720,
viewportWidth: 1280,
chromeWebSecurity: false,
experimentalInteractiveRunEvents: true,
component: {
specPattern: 'ext/**/*.cy.js',
devServer: {
@@ -31,6 +32,12 @@ module.exports = defineConfig({
});
},
});

// Shutdown the server after `yarn cypress run --component completes
// This ensures that c8 outputs the lcov.info file properly
on('after:run', () => {
return fetch('http://localhost:9000/shutdown');
});
},
},
});
31 changes: 31 additions & 0 deletions ext/Api.js
Original file line number Diff line number Diff line change
@@ -110,6 +110,37 @@ export default class API {
});
}

/**
* @param id {string}
*/
delete(ids) {
return fetch(`${this.apiURL.toString()}/cache`, {
headers: {
'Content-Type': 'application/json',
},
method: 'POST',
body: JSON.stringify({
action: {
type: 'delete',
payload: ids,
},
}),
});
}

updateCache(id, values) {
return fetch(`${this.apiURL.toString()}/cache`, {
headers: { 'Content-Type': 'application/json' },
method: 'POST',
body: JSON.stringify({
action: {
type: 'update',
payload: { id, values },
},
}),
});
}

/**
* @param blockNetworkRequests {boolean}
*/
43 changes: 34 additions & 9 deletions ext/App.cy.js
Original file line number Diff line number Diff line change
@@ -4,26 +4,36 @@ import App from './App.svelte';
let api;
before(async () => {
await cy.task('set-jambox-config', {
blockNetworkRequests: true,
blockNetworkRequests: false,
forward: {
'http://jambox-test.com/path': {
target: 'http://localhost:7777',
paths: ['**'],
},
},
cache: {
dir: '.jambox',
write: 'auto',
stage: ['jambox-test.com/**'],
},
});
api = await API.create();
});

describe('Web Extension', () => {
it('can display seen requests', () => {
// Jambox should generate a static hash for the URL below
const HASH = '2be35430d93be811753ecfd6ba828878';
const testURL = 'http://jambox-test.com/returnThisAsJson';
cy.mount(App, { props: { api } });

cy.request(testURL);

// Additional requests to fill up the cache
cy.request('http://jambox-test.com/pathA');
cy.request('http://jambox-test.com/pathB');
cy.request('http://jambox-test.com/pathC');

cy.get(`[data-cy-id="${testURL}"]`).as('request');

cy.get('@request').contains('200');
@@ -51,15 +61,30 @@ describe('Web Extension', () => {

cy.get('[data-cy-id="cache-link"]').click();

// Same modal as the waterfall should be available for cache
cy.get('[data-cy-id="cache-id"]').click();
cy.get('@modal').contains(testURL);
cy.get('[data-cy-id="select-response-tab"]').click();
cy.get('@modal').contains('path');
cy.get('@modal').contains('/returnThisAsJson');
cy.get(`[data-cy-id="cache-cell-edit-${HASH}"]`).as('test-edit');
cy.get('@test-edit').click();
cy.get('[data-cy-id="cache-detail"]').contains(testURL);

cy.get('[data-cy-id="modal-background"]').click({ force: true });
cy.get('[data-cy-id="cache-detail"]').contains('path');
cy.get('[data-cy-id="cache-detail"]').contains('/returnThisAsJson');

cy.get('@modal').should('not.exist');
cy.get('[data-cy-id="cache-breadcrumb-link"]').click();

cy.get('[data-cy-id="cache-detail"]').should('not.exist');

// clear cache
cy.get('@test-edit').click();
cy.get('[data-cy-id="cache-delete"]').click();
cy.get('[data-cy-id="cache-detail"]').should('not.exist');
cy.get('@test-edit')
.should('not.exist')
.then(() => {
// Delete the rest of the requests
return api.delete([
'ba20ccbb470042f3200692cad1926c1c',
'f4c55ab257c689845921746061bfeb73',
'cd4482b36a608021cd943786ecb54c5d',
]);
});
});
});
5 changes: 4 additions & 1 deletion ext/App.svelte
Original file line number Diff line number Diff line change
@@ -18,14 +18,16 @@
api.getConfig().then((payload) => {
store.update((state) => reducer(state, { type: 'config', payload }));
});
api.getCache().then((payload) => {
store.update((state) => reducer(state, { type: 'cache.load', payload }));
});
$: {
cleanup?.();
pauseChecked = $store.config.pause;
cleanup = api.subscribe((action) => {
if (action.type === 'config') {
console.log(action);
chrome.notifications?.create('', {
title: 'Jambox Config Updated!',
message: `Loaded ${action.payload.filepath}`,
@@ -75,6 +77,7 @@
{/if}
{#if path === '/Cache'}
<Cache
cache={$store.cache}
{api}
onSelection={(row) => {
selection = row;
54 changes: 54 additions & 0 deletions ext/Cache/Breadcrumb.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<script>
/**
* A very basic Breadcrumb
*/
export let cacheEntry;
export let onCacheClick;
</script>

<ul>
<li>
{#if cacheEntry != null}
<a
data-cy-id="cache-breadcrumb-link"
href="/Cache"
on:click={(e) => {
e.preventDefault();
onCacheClick();
}}>Cache</a
>
{:else}
<li>Cache</li>
{/if}
</li>
<li><div class="split">/</div></li>
{#if cacheEntry != null}
<li>{cacheEntry.id}</li>
{/if}
</ul>

<style>
ul {
display: flex;
align-items: center;
flex-wrap: wrap;
flex: 0 1 auto;
list-style-type: none;
margin: 0;
padding: 0 5px;
}
li {
align-items: center;
display: inline-flex;
font-size: 14px;
}
ul > :last-child {
color: var(--gc-cerulean);
}
.split {
padding: 0 4px 0 2px;
}
</style>
28 changes: 25 additions & 3 deletions ext/Cache/Cell.svelte
Original file line number Diff line number Diff line change
@@ -1,9 +1,31 @@
<script>
export let row;
export let col;
export let onEdit;
console.log(row, col);
const value = row[col.key];
let value, cyID;
$: value = row[col.key];
$: cyID = col.key === 'edit' ? `edit-${row.id}` : col.key;
</script>

<span data-cy-id="cache-{col.key}">{value}</span>
<div class="Cell">
{#if col.key === 'edit'}
<button
inline
data-cy-id="cache-cell-{cyID}"
on:click={() => {
onEdit(row.id);
}}>Edit</button
>
{:else}
<span data-cy-id="cache-cell-{cyID}">{value}</span>
{/if}
</div>

<style>
.Cell {
display: flex;
flex-direction: column;
align-items: center;
}
</style>
56 changes: 56 additions & 0 deletions ext/Cache/Detail.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<script>
import { JSONEditor } from 'svelte-jsoneditor';
export let cacheEntry;
export let onDelete;
export let onUpdateResponse;
let changes = null;
function onChange(prev, curr) {
changes = curr.json;
}
</script>

<div data-cy-id="cache-detail" class="Wrapper">
<button data-cy-id="cache-delete" on:click={() => onDelete(cacheEntry.id)}
>Delete</button
>
<div class="Request">
<div>Request</div>
<JSONEditor
content={{ json: cacheEntry.request }}
readOnly
mainMenuBar={false}
/>
</div>
<div>
<div>
Response
<button
class="inline"
disabled={changes === null}
on:click={() => {
onUpdateResponse(changes);
changes = null;
}}>Update (not yet implemented)</button
>
</div>
<JSONEditor content={{ json: cacheEntry.response }} {onChange} />
</div>
</div>

<style>
.inline {
display: inline;
}
.Wrapper {
display: flex;
flex-direction: column;
margin-top: 10px;
width: 100%;
}
.Request {
margin-bottom: 20px;
height: 50%;
}
</style>
Loading

0 comments on commit 3b372a1

Please sign in to comment.