Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add screenshot support #34

Merged
merged 2 commits into from
Aug 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 60 additions & 105 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,39 @@ A static start page to get to your most important links, **FAST**. You can use t
- Quick link preview
- Search (with search provider and tag support)
- Docker support
- Local Config management
- Multiple profiles
- Load remote profile
- Caching strategies
- PWA support
- Keyboard shortcuts
- Read Only mode
- Full keyboard navigation support

## Screens

Landing page

![Landing Page](docs/assets/screen.png)
| Desktop | Mobile |
| ----------------------------------------------------- | --------------------------------------------------- |
| ![Landing Page Desktop](docs/assets/main-desktop.png) | ![Landing Page Mobile](docs/assets/main-mobile.png) |

Quickly find links

![Quickly find links](docs/assets/screen-search.png)
| Desktop | Mobile |
| ------------------------------------------------------- | ----------------------------------------------------- |
| ![Landing Page Desktop](docs/assets/search-desktop.png) | ![Landing Page Mobile](docs/assets/search-mobile.png) |

Easily edit links

![Locally edit links](docs/assets/screen-edit.png)
| Desktop | Mobile |
| ----------------------------------------------------- | --------------------------------------------------- |
| ![Landing Page Desktop](docs/assets/edit-desktop.png) | ![Landing Page Mobile](docs/assets/edit-mobile.png) |

Locally manage config using JSON

![Locally manage config using JSON](docs/assets/screen-config.png)
| Desktop | Mobile |
| --------------------------------------------------------------- | ------------------------------------------------------------- |
| ![Landing Page Desktop](docs/assets/config-manager-desktop.png) | ![Landing Page Mobile](docs/assets/config-manager-mobile.png) |

Drag & drop config file

Expand Down Expand Up @@ -112,116 +123,60 @@ e.g.:

### Using Config

Since this is a static website, the only way to permanently update the links is to modify the `config.json` file. If using the pre built version, just update the `config.json` file in the release zip. During development, update the config in the `assets` folder since the build will override any other config file.
Since this is a static website, all edits made are local and the new config must uploaded to a server from where the configs can be fetched. To make this process easier, Hiccup comes with a built in config manager. The config manager allows you to:

To update config on a local browser instance, use the online config editor using the ⚙️ icon. This will persist the config across sessions. The local editor allows to:
- Load a config file from either URL or local file
- Manage multiple configs (Preview, Select, Sync, Delete)
- Download config file

- Edit the raw local config
- Sync the configuration from `./configs/config.json` file
- Download the latest valid config file
- Upload a local config file. (psst.. if the file has issues, no problem! The editor will still load it and show you the errors until you can save it)
- Save the config to **LocalStorage**
you can also additionally share hiccup with a preloaded config using the `config` url parameter.

#### Config structure
e.g.

```js
{
// Uses semantic versioning
"version": "1.0",
// featured and catagories are optional sections. Remove them to use the page without it.
"featured": [{
"name": "Link name as seen on the card", // required
"link": "link", // required
"background": "path to background image", // optional
"tags": "space spearated tags for searching" //optional
}, {
// ... Other featured links
}],
"catagories": [{
"name": "Category name", // required
"links": [{
"name": "Link name as seen on the card", // required
"link": "link", // required
"tags": "space spearated tags for searching" //optional
}, {
// ... Other category links
}]
}, {
// ... Other categorys
}],
"metadata": {
"readonly": false // default
}
}
```
http://designedbyashw.in/test/hiccup?config=http://your-url.com/config.json
```

> Since this is a CORS request, the server should allow requests from the source domain. Github Gists are an easy way to save remote config's

#### Using with github gists

To save a config on github gists.

1. Create the hiccup view you want and download the config.
1. Copy the contents of the file to the gist
1. Click Creat a **Public** Gist
1. Copy the url and add `/raw` to the end. This is now your config URL

Share the config with anyone to load in their instance of hiccup

#### Migrations

If you were using an older version of Hiccup (< v0.4.x), the config manager will automatically recover the old cached config and promt you to save it using the new version. download the recovered config and redistribute it as needed.

All the config information is stored in **LocalStorage** and never sent to a server anywhere!

#### Config structure

Refer to the [JSON Scheme file](src/modules/validateConfig/schema.json) for the latest schema.

#### Sample config
### Caching

The app now supports 4 caching strategies, these are useful if you dont want to frequently update your configs or run it completely offine

Strategies:

- `cache`: Use only the local cache to save and fetch data
- `network`: Use only the network values and fail if you cannot get it
- `cache-first`: If not found in the cache, fallback to the remote URL
- `network-first`: (Default) If not found in the remote server, fallback to the cached value

You can set this value using the URL parameter `cache`

e.g.

```
{
"version": "1.0".
"featured": [{
"name": "Featured Link",
"link": "http://google.com",
"background": "/assets/card.png"
}, {
"name": "Another Feaured link",
"link": "http://google.com"
}, {
"name": "One more",
"link": "http://google.com"
}, {
"name": "Oh no!!!",
"link": "http://google.com",
"tags": "space separated tags"
}],
"categories": [{
"title": "Category 1",
"links": [{
"name": "Link 1",
"link": "http://google.com"
}, {
"name": "Link 2",
"link": "http://google.com"
}]
}, {
"title": "Category 2",
"links": [{
"name": "Link 1",
"link": "http://google.com"
}, {
"name": "Link 2",
"link": "http://google.com"
}]
}, {
"title": "Category 3",
"links": [{
"name": "Link 1",
"link": "http://google.com",
"tags": "more searchable tags"
}]
}, {
"title": "Category 4",
"links": [{
"name": "Link 1",
"link": "http://google.com"
}, {
"name": "Link 2",
"link": "http://google.com"
}, {
"name": "Link 3",
"link": "http://google.com"
}, {
"name": "Link 4",
"link": "http://google.com"
}]
}],
"metadata": {
"readonly": false
}
}
http://designedbyashw.in/test/hiccup?cache=network
```

## Available Scripts for development
Expand Down
6 changes: 3 additions & 3 deletions cypress/e2e/base.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ describe('Basic tests', () => {
.contains('First Default Featured Link')

cy.clickSettings()
cy.getConfigPreview('default')
cy.getManagedConfig('default', 'preview')
.should('contain.text', 'Default Config')
.should('contain.text', 'Active')
})
Expand All @@ -27,7 +27,7 @@ describe('Basic tests', () => {
.contains('This is a dummy config')

cy.clickSettings()
cy.getConfigPreview('dummy')
cy.getManagedConfig('dummy', 'preview')
.should('contain.text', 'Dummy Config')
.should('contain.text', 'Active')
})
Expand Down Expand Up @@ -55,6 +55,6 @@ describe('Basic tests', () => {

cy.clickSettings()

cy.getPreviewingConfig().should('contain', ' - Editing')
cy.getManagedConfig().should('contain', ' - Editing')
})
})
22 changes: 11 additions & 11 deletions cypress/e2e/config.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,21 @@ describe('Config Manager', () => {

it('should be able to preview configs', () => {
cy.findByTestId('file-viewer').find('#id').should('not.contain', 'empty')
cy.getConfigPreview('empty').click()
cy.getManagedConfig('empty').click()
cy.findByTestId('file-viewer').find('#id').should('contain', 'empty')
})

it('should be able to switch configs', () => {
cy.findByTestId('file-viewer').find('#id').should('not.contain', 'empty')
cy.getConfigActivate('empty').click()
cy.getConfigPreview('empty').should('contain.text', 'Active')
cy.getManagedConfig('empty', 'activate').click()
cy.getManagedConfig('empty').should('contain.text', 'Active')
})

it('should be able to load remote config', () => {
cy.intercept('GET', 'http://dummyconfig.com', { fixture: 'dummy' })
cy.submitUrlInput('http://dummyconfig.com')
cy.findByTestId('file-viewer').find('#id').should('contain', 'dummy')
cy.getConfigPreview('dummy').should('contain.text', 'Active')
cy.getManagedConfig('dummy', 'preview').should('contain.text', 'Active')
})

it('should be able to sync config', () => {
Expand All @@ -34,7 +34,7 @@ describe('Config Manager', () => {
cy.intercept('GET', '**/configs/config.json', {
fixture: 'default-after-sync',
}).as('sync')
cy.getConfigSync('default').click()
cy.getManagedConfig('default', 'sync').click()
cy.findByTestId('file-viewer')
.find('#title')
.should('contain', 'Default Synced Config')
Expand All @@ -44,16 +44,16 @@ describe('Config Manager', () => {
cy.intercept('GET', 'http://dummyconfig.com', { fixture: 'dummy' })
cy.submitUrlInput('http://dummyconfig.com')
cy.findByTestId('file-viewer').find('#id').should('contain', 'dummy')
cy.getConfigPreview('dummy').should('contain.text', 'Active')
cy.getManagedConfig('dummy', 'preview').should('contain.text', 'Active')

// disabled delete default config
cy.getConfigDelete('default').should('be.disabled')
cy.getConfigPreview('default').should('exist')
cy.getManagedConfig('default', 'delete').should('be.disabled')
cy.getManagedConfig('default', 'preview').should('exist')

// Delete dummy config
cy.getConfigPreview('dummy').should('exist')
cy.getConfigDelete('dummy').click()
cy.getConfigPreview('dummy').should('not.exist')
cy.getManagedConfig('dummy', 'preview').should('exist')
cy.getManagedConfig('dummy', 'delete').click()
cy.getManagedConfig('dummy', 'preview').should('not.exist')
})

it('should download config', () => {
Expand Down
58 changes: 58 additions & 0 deletions cypress/e2e/visual.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Run this only when you need updated screenshots
// Run on a reasonably large monitor so that scrollbars dont appear. This seesm to be a bug with cypress screenshot
describe.skip('Screenshots', () => {
const screens: {
type: string
orientation?: Cypress.ViewportOrientation
viewport: Cypress.ViewportPreset
}[] = [
{
type: 'desktop',
viewport: 'macbook-13',
},
{
type: 'mobile',
viewport: 'iphone-8',
},
]

beforeEach(() => {
// TODO: get app url dynamically
cy.visit('http://localhost:3000')
cy.intercept('GET', '**/configs/config.json', { fixture: 'default' })
cy.intercept('GET', '**/assets/*').as('image')
})

screens.forEach(({ type, viewport, orientation }) => {
it(`should capture all major ${type} screens`, () => {
cy.viewport(viewport, orientation ?? 'portrait')
// Wait for app to load
cy.wait('@image')
cy.get('.toast').should('be.visible')
cy.get('.toast').should('be.hidden')

// Landing page
cy.screenshotPreviewImage(`main-${type}`)

// Search
cy.typeInSearchBar('Fea')
cy.screenshotPreviewImage(`search-${type}`)
cy.typeInSearchBar('{esc}')

// Hotkey edit
cy.blurSearch().type('{cmd+e}')
cy.screenshotPreviewImage(`edit-${type}`)

// Exit edit mode and hotkey config maager
cy.blurSearch().type('{cmd+e}')
cy.blurSearch().type('{cmd+k}')
cy.screenshotPreviewImage(`config-manager-${type}`)
cy.closeModal()

// Hotkey modal
cy.get('body').type('{cmd+/}')
cy.screenshotPreviewImage(`hotkey-${type}`)
cy.closeModal()
})
})
})
10 changes: 5 additions & 5 deletions cypress/support/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ declare namespace Cypress {
* @example cy.clickOnMyJourneyInCandidateCabinet()
*/
clickSettings(): Chainable<null>
getConfigPreview(configId: string): Chainable<null>
getConfigActivate(configId: string): Chainable<null>
getConfigSync(configId: string): Chainable<null>
getConfigDelete(configId: string): Chainable<null>
getPreviewingConfig(): Chainable<null>
closeModal(): Chainable<null>
typeInSearchBar(test: string): Chainable<null>
screenshotPreviewImage(name: string): Chainable<null>
getManagedConfig(id?: string, action?: ConfigAction): Chainable<null>

submitUrlInput(url: string): Chainable<null>
getEditLinkModal(): Chainable<null>
getCachedConfigs(): Chainable<null>
Expand Down
Loading