Introduce way to install update directly from tray. Make application updater unit testable... (#5433)

* Extract product name as injectable

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Make tray items comply with Open Closed Principle

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Replace duplicated overrides with global

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Add behaviour for navigating to preferences using tray

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Introduce a tray item for updating application

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Tweak naming

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Tweak more naming

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Remove redundant indirection

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Tweak more naming

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Introduce injectable for package.json being side-effect

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Relocate file to directory containing feature

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Switch to using injectable for limiting side effect

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Add missing injection token for implementation of tray item

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Remove resetting state for update is ready to be installed for being unclear

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Kill dead code

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Make label of tray item reactive

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Extract updating is enabled to separate injectable

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Introduce competition for tray

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Expand scope of behaviour for updating using tray also contain checking for updates

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Remove dead code

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Kill dead code

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Implement checking of updates from multiple update channels

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Start installing updates automatically when quitting application

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Show application window when checking of updates has happened

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Show notifications and dialog for downloading update

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Implement naive notifications for version updates

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Implement checking of Electron specific updates as responsibility

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Implement downloading of Electron specific updates as responsibility

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Introduce competition for channel abstraction

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Remove redundant global override

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Fix typing after enabling strict mode

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Introduce abstraction for a state that is shared between environments

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Extract states of application update to be usable from all environments

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Handle failing download of update

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Make code for window visibility actually work

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Consolidate code for sending messages between processes to a window

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Split bloated dependency in smaller pieces

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Make state of download progress accessible from all environments

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Rename files for accuracy

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Move channel abstraction to more global directory

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Enhance typing of channels and sync-box

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Consolidate channel abstraction types

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Update asyncFn to support strict mode

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Fix snapshot after rebase

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Add missing global override

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Introduce injection token for channels to allow injecting all of them at once

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Add notifications about change in update status

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Rename property for accuracy

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Tweak code style

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Make notifications unit testable in behaviours

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Add implementation for asking boolean over processes

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Reorganize responsibilities for checking updates

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Reorganize tests for installing update under separate scenarios

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Make stuff happening when root frame is rendered unit testable

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Introduce periodical check for updates

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Allow downgrading app versions

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Switch to using competition for checking of updates in application menu

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Kill dead code

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Make test less prone to fail for wrong reason

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Remove redundant boilerplate

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Make tests for specific migrations less prone to failing for wrong reason

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Move shared stuff under common

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Switch to using single source of truth for selected update channel

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Extract tests for installing update from different update channels to separate scenario

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Add missing global override

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Switch to using release channel of installed application version as default value for selected update channel

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Consolidate usage of channel abstraction to same implementation

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Make Channel abstraction support return values

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Fix direct calling of runnables

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Synchronize initial values of sync boxes when window starts

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Add missing global override

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Tweak message of question from user

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Consolidate names of directories

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Add TODO

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Remove unimplemented scenario from test

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Simplify test

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Improve name of test

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Remove redundant overrides

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Fix code style

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Make Animate deterministic in unit tests

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Simplify naming

Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>

Signed-off-by: Iku-turso <mikko.aspiala@gmail.com>

* Simplify more naming

Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>

Signed-off-by: Iku-turso <mikko.aspiala@gmail.com>

* Simplify even more naming

Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>

Signed-off-by: Iku-turso <mikko.aspiala@gmail.com>

* Simplify more and more naming

Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>

Signed-off-by: Iku-turso <mikko.aspiala@gmail.com>

* Add todo for cleaning unacceptable code encountered

Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>

Signed-off-by: Iku-turso <mikko.aspiala@gmail.com>

* Improve name of behaviour

Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>

Signed-off-by: Iku-turso <mikko.aspiala@gmail.com>

* Make unit test more strict

Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>

Signed-off-by: Iku-turso <mikko.aspiala@gmail.com>

* Enhance name of behaviour

Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>

Signed-off-by: Iku-turso <mikko.aspiala@gmail.com>

* Introduce dependency to get random IDs

Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>

Signed-off-by: Iku-turso <mikko.aspiala@gmail.com>

* Make asking of boolean value from user not require explicit ID for question

Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>

Signed-off-by: Iku-turso <mikko.aspiala@gmail.com>

* Simplify code for asking of boolean value from user

Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>

Signed-off-by: Iku-turso <mikko.aspiala@gmail.com>

* Make setting of initial state for sync boxes not trigger irrelevant messaging to main

Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>

Signed-off-by: Iku-turso <mikko.aspiala@gmail.com>

* Make a channel have default type for sent and returned message

Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>

Signed-off-by: Iku-turso <mikko.aspiala@gmail.com>

* Introduce higher order function to log errors in decorated functions

Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>

Signed-off-by: Iku-turso <mikko.aspiala@gmail.com>

* Export type for error logging

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Tweak test name

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Introduce higher order function for suppressing errors

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Relocate some explicit error handlings to proper level of abstraction

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Make higher order function for logging errors support asynchronous rejecting with non error instance

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Make overridden version of application exactly the one required by unit test

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Mark injectable causing side effects

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Revert not required changes

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Make code for asserting a promise more strict

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Make dependencies readonly

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Remove duplication for disposers

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Implement initial values for sync-boxes

Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>

Signed-off-by: Iku-turso <mikko.aspiala@gmail.com>

* Separate concept of message and request channels

Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>

Signed-off-by: Iku-turso <mikko.aspiala@gmail.com>

* Introduce tests for requesting from channel in renderer

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Implement requesting from renderer in main

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Revert "Implement requesting from renderer in main"

This reverts commit d3e7899d7900516f3dbfacdb317a453202318305.

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Tweak typing of request channel listeners to get rid of unexpected undefined

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Remove unused variable

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Tweak timing of sentry setup

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Require messages for MessageChannels be JsonValues for serialization

Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>

Signed-off-by: Iku-turso <mikko.aspiala@gmail.com>

* Require requests and responses for RequestChannels be JsonValues for serialization

Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>

Signed-off-by: Iku-turso <mikko.aspiala@gmail.com>

* Make different MessageChannels not require explicit "extends JsonObject"

Note: Non-escaped lint breaks type here for forcing interface over type. Reasonable effort brought no understanding for what is the relevant difference between the two.

Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>

Signed-off-by: Iku-turso <mikko.aspiala@gmail.com>

* Make a primitive argument an object for readability

Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>

Signed-off-by: Iku-turso <mikko.aspiala@gmail.com>

* Make typing of higher order function for error suppression not lie

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Serialize messages in channels to make IPC not blow up

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Introduce a way to make intentional orphan promises uniform, controllable and deliberate

Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>

Signed-off-by: Iku-turso <mikko.aspiala@gmail.com>

* Make downloading of update and what follows more deliberate as orphan promise

Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>

Signed-off-by: Iku-turso <mikko.aspiala@gmail.com>

* Move utility function under directory

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Move another utility function under directory

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Fix incorrect name of file

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Remove redundant code

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Kill dead code

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Round percentage of update download progress in tray

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Fix rebase conflicts

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Fix CheckForUpdate type errors

Signed-off-by: Sebastian Malton <sebastian@malton.name>

Co-authored-by: Iku-turso <mikko.aspiala@gmail.com>
Co-authored-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
authored and GitHub committed 2022-06-03 11:21:36 +03:00
1 parent e1c1e00a2b
commit b414f9e06d
229 files changed
+8652 -1217

No files matched your search

@@ -1,11 +1,20 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`extension special characters in page registrations renders 1`] = `<div />`;
exports[`extension special characters in page registrations renders 1`] = `
<div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
exports[`extension special characters in page registrations when navigating to route with ID having special characters renders 1`] = `
<div>
<div>
Some page
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -1,12 +1,21 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`navigate to extension page renders 1`] = `<div />`;
exports[`navigate to extension page renders 1`] = `
<div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
exports[`navigate to extension page when extension navigates to child route renders 1`] = `
<div>
<div>
Child page
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -31,6 +40,9 @@ exports[`navigate to extension page when extension navigates to route with param
Some button
</button>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -55,6 +67,9 @@ exports[`navigate to extension page when extension navigates to route without pa
Some button
</button>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -79,5 +94,8 @@ exports[`navigate to extension page when extension navigates to route without pa
Some button
</button>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -8,6 +8,9 @@ exports[`navigating between routes given route with optional path parameters whe
"someOtherParameter": "some-other-value"
}
</pre>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -16,5 +19,8 @@ exports[`navigating between routes given route without path parameters when navi
<div>
Some component
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -1,6 +1,12 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`add-cluster - navigation using application menu renders 1`] = `<div />`;
exports[`add-cluster - navigation using application menu renders 1`] = `
<div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
exports[`add-cluster - navigation using application menu when navigating to add cluster using application menu renders 1`] = `
<div>
@@ -85,5 +91,8 @@ exports[`add-cluster - navigation using application menu when navigating to add
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -6,16 +6,17 @@
import type { RenderResult } from "@testing-library/react";
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import isAutoUpdateEnabledInjectable from "../../main/is-auto-update-enabled.injectable";
import React from "react";
// TODO: Make components free of side effects by making them deterministic
jest.mock("../../renderer/components/tooltip/tooltip", () => ({
Tooltip: () => null,
}));
jest.mock("../../renderer/components/tooltip/withTooltip", () => ({
withTooltip: (Target: any) => ({ tooltip, tooltipOverrideDisabled, ...props }: any) => <Target {...props} />,
}));
jest.mock("../../renderer/components/monaco-editor/monaco-editor", () => ({
MonacoEditor: () => null,
}));
@@ -25,9 +26,7 @@ describe("add-cluster - navigation using application menu", () => {
let rendered: RenderResult;
beforeEach(async () => {
applicationBuilder = getApplicationBuilder().beforeApplicationStart(({ mainDi }) => {
mainDi.override(isAutoUpdateEnabledInjectable, () => () => false);
});
applicationBuilder = getApplicationBuilder();
rendered = await applicationBuilder.render();
});
@@ -0,0 +1,536 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`installing update using tray when started renders 1`] = `
<body>
<div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
</body>
`;
exports[`installing update using tray when started when user checks for updates using tray renders 1`] = `
<body>
<div>
<div
class="Notifications flex column align-flex-end"
>
<div
class="Animate opacity notification flex info enter"
style="--enter-duration: 100ms; --leave-duration: 100ms;"
>
<div
class="box"
>
<i
class="Icon material focusable"
>
<span
class="icon"
data-icon-name="info_outline"
>
info_outline
</span>
</i>
</div>
<div
class="message box grow"
>
Checking for updates...
</div>
<div
class="box"
>
<i
class="Icon close material interactive focusable"
data-testid="close-notification-for-notification_13"
tabindex="0"
>
<span
class="icon"
data-icon-name="close"
>
close
</span>
</i>
</div>
</div>
</div>
</div>
</body>
`;
exports[`installing update using tray when started when user checks for updates using tray when new update is discovered renders 1`] = `
<body>
<div>
<div
class="Notifications flex column align-flex-end"
>
<div
class="Animate opacity notification flex info enter"
style="--enter-duration: 100ms; --leave-duration: 100ms;"
>
<div
class="box"
>
<i
class="Icon material focusable"
>
<span
class="icon"
data-icon-name="info_outline"
>
info_outline
</span>
</i>
</div>
<div
class="message box grow"
>
Checking for updates...
</div>
<div
class="box"
>
<i
class="Icon close material interactive focusable"
data-testid="close-notification-for-notification_96"
tabindex="0"
>
<span
class="icon"
data-icon-name="close"
>
close
</span>
</i>
</div>
</div>
<div
class="Animate opacity notification flex info enter"
style="--enter-duration: 100ms; --leave-duration: 100ms;"
>
<div
class="box"
>
<i
class="Icon material focusable"
>
<span
class="icon"
data-icon-name="info_outline"
>
info_outline
</span>
</i>
</div>
<div
class="message box grow"
>
Download for version some-version started...
</div>
<div
class="box"
>
<i
class="Icon close material interactive focusable"
data-testid="close-notification-for-notification_99"
tabindex="0"
>
<span
class="icon"
data-icon-name="close"
>
close
</span>
</i>
</div>
</div>
</div>
</div>
</body>
`;
exports[`installing update using tray when started when user checks for updates using tray when new update is discovered when download fails renders 1`] = `
<body>
<div>
<div
class="Notifications flex column align-flex-end"
>
<div
class="Animate opacity notification flex info enter"
style="--enter-duration: 100ms; --leave-duration: 100ms;"
>
<div
class="box"
>
<i
class="Icon material focusable"
>
<span
class="icon"
data-icon-name="info_outline"
>
info_outline
</span>
</i>
</div>
<div
class="message box grow"
>
Checking for updates...
</div>
<div
class="box"
>
<i
class="Icon close material interactive focusable"
data-testid="close-notification-for-notification_149"
tabindex="0"
>
<span
class="icon"
data-icon-name="close"
>
close
</span>
</i>
</div>
</div>
<div
class="Animate opacity notification flex info enter"
style="--enter-duration: 100ms; --leave-duration: 100ms;"
>
<div
class="box"
>
<i
class="Icon material focusable"
>
<span
class="icon"
data-icon-name="info_outline"
>
info_outline
</span>
</i>
</div>
<div
class="message box grow"
>
Download for version some-version started...
</div>
<div
class="box"
>
<i
class="Icon close material interactive focusable"
data-testid="close-notification-for-notification_152"
tabindex="0"
>
<span
class="icon"
data-icon-name="close"
>
close
</span>
</i>
</div>
</div>
<div
class="Animate opacity notification flex info enter"
style="--enter-duration: 100ms; --leave-duration: 100ms;"
>
<div
class="box"
>
<i
class="Icon material focusable"
>
<span
class="icon"
data-icon-name="info_outline"
>
info_outline
</span>
</i>
</div>
<div
class="message box grow"
>
Download of update failed
</div>
<div
class="box"
>
<i
class="Icon close material interactive focusable"
data-testid="close-notification-for-notification_157"
tabindex="0"
>
<span
class="icon"
data-icon-name="close"
>
close
</span>
</i>
</div>
</div>
</div>
</div>
</body>
`;
exports[`installing update using tray when started when user checks for updates using tray when new update is discovered when download succeeds renders 1`] = `
<body>
<div>
<div
class="Notifications flex column align-flex-end"
>
<div
class="Animate opacity notification flex info enter"
style="--enter-duration: 100ms; --leave-duration: 100ms;"
>
<div
class="box"
>
<i
class="Icon material focusable"
>
<span
class="icon"
data-icon-name="info_outline"
>
info_outline
</span>
</i>
</div>
<div
class="message box grow"
>
Checking for updates...
</div>
<div
class="box"
>
<i
class="Icon close material interactive focusable"
data-testid="close-notification-for-notification_215"
tabindex="0"
>
<span
class="icon"
data-icon-name="close"
>
close
</span>
</i>
</div>
</div>
<div
class="Animate opacity notification flex info enter"
style="--enter-duration: 100ms; --leave-duration: 100ms;"
>
<div
class="box"
>
<i
class="Icon material focusable"
>
<span
class="icon"
data-icon-name="info_outline"
>
info_outline
</span>
</i>
</div>
<div
class="message box grow"
>
Download for version some-version started...
</div>
<div
class="box"
>
<i
class="Icon close material interactive focusable"
data-testid="close-notification-for-notification_218"
tabindex="0"
>
<span
class="icon"
data-icon-name="close"
>
close
</span>
</i>
</div>
</div>
<div
class="Animate opacity notification flex info enter"
style="--enter-duration: 100ms; --leave-duration: 100ms;"
>
<div
class="box"
>
<i
class="Icon material focusable"
>
<span
class="icon"
data-icon-name="info_outline"
>
info_outline
</span>
</i>
</div>
<div
class="message box grow"
>
<div
class="flex column gaps"
data-testid="ask-boolean-some-irrelevant-random-id"
>
<b>
Update Available
</b>
<p>
Version some-version of Lens IDE is available and ready to be installed. Would you like to update now?
Lens should restart automatically, if it doesn't please restart manually. Installed extensions might require updating.
</p>
<div
class="flex gaps row align-left box grow"
>
<button
class="Button light"
data-testid="ask-boolean-some-irrelevant-random-id-button-yes"
type="button"
>
Yes
</button>
<button
class="Button active outlined"
data-testid="ask-boolean-some-irrelevant-random-id-button-no"
type="button"
>
No
</button>
</div>
</div>
</div>
<div
class="box"
>
<i
class="Icon close material interactive focusable"
data-testid="close-notification-for-ask-boolean-for-some-irrelevant-random-id"
tabindex="0"
>
<span
class="icon"
data-icon-name="close"
>
close
</span>
</i>
</div>
</div>
</div>
</div>
</body>
`;
exports[`installing update using tray when started when user checks for updates using tray when no new update is discovered renders 1`] = `
<body>
<div>
<div
class="Notifications flex column align-flex-end"
>
<div
class="Animate opacity notification flex info enter"
style="--enter-duration: 100ms; --leave-duration: 100ms;"
>
<div
class="box"
>
<i
class="Icon material focusable"
>
<span
class="icon"
data-icon-name="info_outline"
>
info_outline
</span>
</i>
</div>
<div
class="message box grow"
>
Checking for updates...
</div>
<div
class="box"
>
<i
class="Icon close material interactive focusable"
data-testid="close-notification-for-notification_48"
tabindex="0"
>
<span
class="icon"
data-icon-name="close"
>
close
</span>
</i>
</div>
</div>
<div
class="Animate opacity notification flex info enter"
style="--enter-duration: 100ms; --leave-duration: 100ms;"
>
<div
class="box"
>
<i
class="Icon material focusable"
>
<span
class="icon"
data-icon-name="info_outline"
>
info_outline
</span>
</i>
</div>
<div
class="message box grow"
>
No new updates available
</div>
<div
class="box"
>
<i
class="Icon close material interactive focusable"
data-testid="close-notification-for-notification_51"
tabindex="0"
>
<span
class="icon"
data-icon-name="close"
>
close
</span>
</i>
</div>
</div>
</div>
</div>
</body>
`;
@@ -0,0 +1,81 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`installing update when started renders 1`] = `
<body>
<div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
</body>
`;
exports[`installing update when started when user checks for updates renders 1`] = `
<body>
<div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
</body>
`;
exports[`installing update when started when user checks for updates when new update is discovered renders 1`] = `
<body>
<div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
</body>
`;
exports[`installing update when started when user checks for updates when new update is discovered when download fails renders 1`] = `
<body>
<div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
</body>
`;
exports[`installing update when started when user checks for updates when new update is discovered when download succeeds renders 1`] = `
<body>
<div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
</body>
`;
exports[`installing update when started when user checks for updates when new update is discovered when download succeeds when user answers not to install the update renders 1`] = `
<body>
<div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
</body>
`;
exports[`installing update when started when user checks for updates when new update is discovered when download succeeds when user answers to install the update renders 1`] = `
<body>
<div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
</body>
`;
exports[`installing update when started when user checks for updates when no new update is discovered renders 1`] = `
<body>
<div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
</body>
`;
@@ -0,0 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`periodical checking of updates given updater is enabled and configuration exists, when started renders 1`] = `
<body>
<div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
</body>
`;
@@ -0,0 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`selection of update stability when started renders 1`] = `
<body>
<div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
</body>
`;
@@ -0,0 +1,87 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import electronUpdaterIsActiveInjectable from "../../main/electron-app/features/electron-updater-is-active.injectable";
import publishIsConfiguredInjectable from "../../main/application-update/publish-is-configured.injectable";
import type { AsyncFnMock } from "@async-fn/jest";
import asyncFn from "@async-fn/jest";
import type { CheckForPlatformUpdates } from "../../main/application-update/check-for-platform-updates/check-for-platform-updates.injectable";
import checkForPlatformUpdatesInjectable from "../../main/application-update/check-for-platform-updates/check-for-platform-updates.injectable";
import processCheckingForUpdatesInjectable from "../../main/application-update/check-for-updates/process-checking-for-updates.injectable";
import selectedUpdateChannelInjectable from "../../common/application-update/selected-update-channel/selected-update-channel.injectable";
import type { DiContainer } from "@ogre-tools/injectable";
import appVersionInjectable from "../../common/get-configuration-file-model/app-version/app-version.injectable";
import { updateChannels } from "../../common/application-update/update-channels";
describe("downgrading version update", () => {
let applicationBuilder: ApplicationBuilder;
let checkForPlatformUpdatesMock: AsyncFnMock<CheckForPlatformUpdates>;
let mainDi: DiContainer;
beforeEach(() => {
jest.useFakeTimers();
applicationBuilder = getApplicationBuilder();
applicationBuilder.beforeApplicationStart(({ mainDi }) => {
checkForPlatformUpdatesMock = asyncFn();
mainDi.override(
checkForPlatformUpdatesInjectable,
() => checkForPlatformUpdatesMock,
);
mainDi.override(electronUpdaterIsActiveInjectable, () => true);
mainDi.override(publishIsConfiguredInjectable, () => true);
});
mainDi = applicationBuilder.dis.mainDi;
});
[
{
updateChannel: updateChannels.latest,
appVersion: "4.0.0-beta",
downgradeIsAllowed: true,
},
{
updateChannel: updateChannels.beta,
appVersion: "4.0.0-beta",
downgradeIsAllowed: false,
},
{
updateChannel: updateChannels.beta,
appVersion: "4.0.0-beta.1",
downgradeIsAllowed: false,
},
{
updateChannel: updateChannels.alpha,
appVersion: "4.0.0-beta",
downgradeIsAllowed: true,
},
{
updateChannel: updateChannels.alpha,
appVersion: "4.0.0-alpha",
downgradeIsAllowed: false,
},
].forEach(({ appVersion, updateChannel, downgradeIsAllowed }) => {
it(`given application version "${appVersion}" and update channel "${updateChannel.id}", when checking for updates, can${downgradeIsAllowed ? "": "not"} downgrade`, async () => {
mainDi.override(appVersionInjectable, () => appVersion);
await applicationBuilder.render();
const selectedUpdateChannel = mainDi.inject(selectedUpdateChannelInjectable);
selectedUpdateChannel.setValue(updateChannel.id);
const processCheckingForUpdates = mainDi.inject(processCheckingForUpdatesInjectable);
processCheckingForUpdates();
expect(checkForPlatformUpdatesMock).toHaveBeenCalledWith(expect.any(Object), { allowDowngrade: downgradeIsAllowed });
});
});
});
@@ -0,0 +1,235 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import type { RenderResult } from "@testing-library/react";
import electronUpdaterIsActiveInjectable from "../../main/electron-app/features/electron-updater-is-active.injectable";
import publishIsConfiguredInjectable from "../../main/application-update/publish-is-configured.injectable";
import type { CheckForPlatformUpdates } from "../../main/application-update/check-for-platform-updates/check-for-platform-updates.injectable";
import checkForPlatformUpdatesInjectable from "../../main/application-update/check-for-platform-updates/check-for-platform-updates.injectable";
import type { AsyncFnMock } from "@async-fn/jest";
import asyncFn from "@async-fn/jest";
import type { DownloadPlatformUpdate } from "../../main/application-update/download-platform-update/download-platform-update.injectable";
import downloadPlatformUpdateInjectable from "../../main/application-update/download-platform-update/download-platform-update.injectable";
import showApplicationWindowInjectable from "../../main/start-main-application/lens-window/show-application-window.injectable";
import progressOfUpdateDownloadInjectable from "../../common/application-update/progress-of-update-download/progress-of-update-download.injectable";
describe("installing update using tray", () => {
let applicationBuilder: ApplicationBuilder;
let checkForPlatformUpdatesMock: AsyncFnMock<CheckForPlatformUpdates>;
let downloadPlatformUpdateMock: AsyncFnMock<DownloadPlatformUpdate>;
let showApplicationWindowMock: jest.Mock;
beforeEach(() => {
applicationBuilder = getApplicationBuilder();
applicationBuilder.beforeApplicationStart(({ mainDi }) => {
checkForPlatformUpdatesMock = asyncFn();
downloadPlatformUpdateMock = asyncFn();
showApplicationWindowMock = jest.fn();
mainDi.override(showApplicationWindowInjectable, () => showApplicationWindowMock);
mainDi.override(
checkForPlatformUpdatesInjectable,
() => checkForPlatformUpdatesMock,
);
mainDi.override(
downloadPlatformUpdateInjectable,
() => downloadPlatformUpdateMock,
);
mainDi.override(electronUpdaterIsActiveInjectable, () => true);
mainDi.override(publishIsConfiguredInjectable, () => true);
});
});
describe("when started", () => {
let rendered: RenderResult;
beforeEach(async () => {
rendered = await applicationBuilder.render();
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("user cannot install update yet", () => {
expect(applicationBuilder.tray.get("install-update")).toBeUndefined();
});
describe("when user checks for updates using tray", () => {
let processCheckingForUpdatesPromise: Promise<void>;
beforeEach(async () => {
processCheckingForUpdatesPromise =
applicationBuilder.tray.click("check-for-updates");
});
it("does not show application window yet", () => {
expect(showApplicationWindowMock).not.toHaveBeenCalled();
});
it("user cannot check for updates again", () => {
expect(
applicationBuilder.tray.get("check-for-updates")?.enabled.get(),
).toBe(false);
});
it("name of tray item for checking updates indicates that checking is happening", () => {
expect(
applicationBuilder.tray.get("check-for-updates")?.label?.get(),
).toBe("Checking for updates...");
});
it("user cannot install update yet", () => {
expect(applicationBuilder.tray.get("install-update")).toBeUndefined();
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
describe("when no new update is discovered", () => {
beforeEach(async () => {
await checkForPlatformUpdatesMock.resolve({
updateWasDiscovered: false,
});
await processCheckingForUpdatesPromise;
});
it("shows application window", () => {
expect(showApplicationWindowMock).toHaveBeenCalled();
});
it("user cannot install update", () => {
expect(applicationBuilder.tray.get("install-update")).toBeUndefined();
});
it("user can check for updates again", () => {
expect(
applicationBuilder.tray.get("check-for-updates")?.enabled.get(),
).toBe(true);
});
it("name of tray item for checking updates no longer indicates that checking is happening", () => {
expect(
applicationBuilder.tray.get("check-for-updates")?.label?.get(),
).toBe("Check for updates");
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
});
describe("when new update is discovered", () => {
beforeEach(async () => {
await checkForPlatformUpdatesMock.resolve({
updateWasDiscovered: true,
version: "some-version",
});
await processCheckingForUpdatesPromise;
});
it("shows application window", () => {
expect(showApplicationWindowMock).toHaveBeenCalled();
});
it("user cannot check for updates again yet", () => {
expect(
applicationBuilder.tray.get("check-for-updates")?.enabled.get(),
).toBe(false);
});
it("name of tray item for checking updates indicates that downloading is happening", () => {
expect(
applicationBuilder.tray.get("check-for-updates")?.label?.get(),
).toBe("Downloading update some-version (0%)...");
});
it("when download progresses with decimals, percentage increases as integers", () => {
const progressOfUpdateDownload = applicationBuilder.dis.mainDi.inject(
progressOfUpdateDownloadInjectable,
);
progressOfUpdateDownload.set({ percentage: 42.424242 });
expect(
applicationBuilder.tray.get("check-for-updates")?.label?.get(),
).toBe("Downloading update some-version (42%)...");
});
it("user still cannot install update", () => {
expect(applicationBuilder.tray.get("install-update")).toBeUndefined();
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
describe("when download fails", () => {
beforeEach(async () => {
await downloadPlatformUpdateMock.resolve({ downloadWasSuccessful: false });
});
it("user cannot install update", () => {
expect(
applicationBuilder.tray.get("install-update"),
).toBeUndefined();
});
it("user can check for updates again", () => {
expect(
applicationBuilder.tray.get("check-for-updates")?.enabled.get(),
).toBe(true);
});
it("name of tray item for checking updates no longer indicates that downloading is happening", () => {
expect(
applicationBuilder.tray.get("check-for-updates")?.label?.get(),
).toBe("Check for updates");
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
});
describe("when download succeeds", () => {
beforeEach(async () => {
await downloadPlatformUpdateMock.resolve({ downloadWasSuccessful: true });
});
it("user can install update", () => {
expect(
applicationBuilder.tray.get("install-update")?.label?.get(),
).toBe("Install update some-version");
});
it("user can check for updates again", () => {
expect(
applicationBuilder.tray.get("check-for-updates")?.enabled.get(),
).toBe(true);
});
it("name of tray item for checking updates no longer indicates that downloading is happening", () => {
expect(
applicationBuilder.tray.get("check-for-updates")?.label?.get(),
).toBe("Check for updates");
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
});
});
});
});
});
@@ -0,0 +1,225 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import quitAndInstallUpdateInjectable from "../../main/electron-app/features/quit-and-install-update.injectable";
import type { RenderResult } from "@testing-library/react";
import electronUpdaterIsActiveInjectable from "../../main/electron-app/features/electron-updater-is-active.injectable";
import publishIsConfiguredInjectable from "../../main/application-update/publish-is-configured.injectable";
import type { CheckForPlatformUpdates } from "../../main/application-update/check-for-platform-updates/check-for-platform-updates.injectable";
import checkForPlatformUpdatesInjectable from "../../main/application-update/check-for-platform-updates/check-for-platform-updates.injectable";
import type { AsyncFnMock } from "@async-fn/jest";
import asyncFn from "@async-fn/jest";
import type { DownloadPlatformUpdate } from "../../main/application-update/download-platform-update/download-platform-update.injectable";
import downloadPlatformUpdateInjectable from "../../main/application-update/download-platform-update/download-platform-update.injectable";
import setUpdateOnQuitInjectable from "../../main/electron-app/features/set-update-on-quit.injectable";
import type { AskBoolean } from "../../main/ask-boolean/ask-boolean.injectable";
import askBooleanInjectable from "../../main/ask-boolean/ask-boolean.injectable";
import showInfoNotificationInjectable from "../../renderer/components/notifications/show-info-notification.injectable";
import processCheckingForUpdatesInjectable from "../../main/application-update/check-for-updates/process-checking-for-updates.injectable";
describe("installing update", () => {
let applicationBuilder: ApplicationBuilder;
let quitAndInstallUpdateMock: jest.Mock;
let checkForPlatformUpdatesMock: AsyncFnMock<CheckForPlatformUpdates>;
let downloadPlatformUpdateMock: AsyncFnMock<DownloadPlatformUpdate>;
let setUpdateOnQuitMock: jest.Mock;
let showInfoNotificationMock: jest.Mock;
let askBooleanMock: AsyncFnMock<AskBoolean>;
beforeEach(() => {
applicationBuilder = getApplicationBuilder();
applicationBuilder.beforeApplicationStart(({ mainDi, rendererDi }) => {
quitAndInstallUpdateMock = jest.fn();
checkForPlatformUpdatesMock = asyncFn();
downloadPlatformUpdateMock = asyncFn();
setUpdateOnQuitMock = jest.fn();
showInfoNotificationMock = jest.fn(() => () => {});
askBooleanMock = asyncFn();
rendererDi.override(showInfoNotificationInjectable, () => showInfoNotificationMock);
mainDi.override(askBooleanInjectable, () => askBooleanMock);
mainDi.override(setUpdateOnQuitInjectable, () => setUpdateOnQuitMock);
mainDi.override(
checkForPlatformUpdatesInjectable,
() => checkForPlatformUpdatesMock,
);
mainDi.override(
downloadPlatformUpdateInjectable,
() => downloadPlatformUpdateMock,
);
mainDi.override(
quitAndInstallUpdateInjectable,
() => quitAndInstallUpdateMock,
);
mainDi.override(electronUpdaterIsActiveInjectable, () => true);
mainDi.override(publishIsConfiguredInjectable, () => true);
});
});
describe("when started", () => {
let rendered: RenderResult;
let processCheckingForUpdates: () => Promise<void>;
beforeEach(async () => {
rendered = await applicationBuilder.render();
processCheckingForUpdates = applicationBuilder.dis.mainDi.inject(processCheckingForUpdatesInjectable);
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
describe("when user checks for updates", () => {
let processCheckingForUpdatesPromise: Promise<void>;
beforeEach(async () => {
processCheckingForUpdatesPromise = processCheckingForUpdates();
});
it("checks for updates", () => {
expect(checkForPlatformUpdatesMock).toHaveBeenCalledWith(
expect.any(Object),
{ allowDowngrade: true },
);
});
it("notifies the user that checking for updates is happening", () => {
expect(showInfoNotificationMock).toHaveBeenCalledWith("Checking for updates...");
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
describe("when no new update is discovered", () => {
beforeEach(async () => {
showInfoNotificationMock.mockClear();
await checkForPlatformUpdatesMock.resolve({
updateWasDiscovered: false,
});
await processCheckingForUpdatesPromise;
});
it("notifies the user", () => {
expect(showInfoNotificationMock).toHaveBeenCalledWith("No new updates available");
});
it("does not start downloading update", () => {
expect(downloadPlatformUpdateMock).not.toHaveBeenCalled();
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
});
describe("when new update is discovered", () => {
beforeEach(async () => {
await checkForPlatformUpdatesMock.resolve({
updateWasDiscovered: true,
version: "some-version",
});
await processCheckingForUpdatesPromise;
});
it("starts downloading the update", () => {
expect(downloadPlatformUpdateMock).toHaveBeenCalled();
});
it("notifies the user that download is happening", () => {
expect(showInfoNotificationMock).toHaveBeenCalledWith("Download for version some-version started...");
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
describe("when download fails", () => {
beforeEach(async () => {
await downloadPlatformUpdateMock.resolve({ downloadWasSuccessful: false });
});
it("does not quit and install update yet", () => {
expect(quitAndInstallUpdateMock).not.toHaveBeenCalled();
});
it("notifies the user about failed download", () => {
expect(showInfoNotificationMock).toHaveBeenCalledWith("Download of update failed");
});
it("does not ask user to install update", () => {
expect(askBooleanMock).not.toHaveBeenCalled();
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
});
describe("when download succeeds", () => {
beforeEach(async () => {
await downloadPlatformUpdateMock.resolve({ downloadWasSuccessful: true });
});
it("does not quit and install update yet", () => {
expect(quitAndInstallUpdateMock).not.toHaveBeenCalled();
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("asks user to install update immediately", () => {
expect(askBooleanMock).toHaveBeenCalledWith({
title: "Update Available",
question:
"Version some-version of Lens IDE is available and ready to be installed. Would you like to update now?\n\n" +
"Lens should restart automatically, if it doesn't please restart manually. Installed extensions might require updating.",
});
});
describe("when user answers to install the update", () => {
beforeEach(async () => {
await askBooleanMock.resolve(true);
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("quits application and installs the update", () => {
expect(quitAndInstallUpdateMock).toHaveBeenCalled();
});
});
describe("when user answers not to install the update", () => {
beforeEach(async () => {
await askBooleanMock.resolve(false);
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("does not quit application and install the update", () => {
expect(quitAndInstallUpdateMock).not.toHaveBeenCalled();
});
});
});
});
});
});
});
@@ -0,0 +1,117 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import type { RenderResult } from "@testing-library/react";
import electronUpdaterIsActiveInjectable from "../../main/electron-app/features/electron-updater-is-active.injectable";
import publishIsConfiguredInjectable from "../../main/application-update/publish-is-configured.injectable";
import type { AsyncFnMock } from "@async-fn/jest";
import asyncFn from "@async-fn/jest";
import processCheckingForUpdatesInjectable from "../../main/application-update/check-for-updates/process-checking-for-updates.injectable";
import periodicalCheckForUpdatesInjectable from "../../main/application-update/periodical-check-for-updates/periodical-check-for-updates.injectable";
const ENOUGH_TIME = 1000 * 60 * 60 * 2;
describe("periodical checking of updates", () => {
let applicationBuilder: ApplicationBuilder;
let processCheckingForUpdatesMock: AsyncFnMock<() => Promise<void>>;
beforeEach(() => {
jest.useFakeTimers();
applicationBuilder = getApplicationBuilder();
applicationBuilder.beforeApplicationStart(({ mainDi }) => {
mainDi.unoverride(periodicalCheckForUpdatesInjectable);
mainDi.permitSideEffects(periodicalCheckForUpdatesInjectable);
processCheckingForUpdatesMock = asyncFn();
mainDi.override(
processCheckingForUpdatesInjectable,
() => processCheckingForUpdatesMock,
);
});
});
describe("given updater is enabled and configuration exists, when started", () => {
let rendered: RenderResult;
beforeEach(async () => {
applicationBuilder.beforeApplicationStart(({ mainDi }) => {
mainDi.override(electronUpdaterIsActiveInjectable, () => true);
mainDi.override(publishIsConfiguredInjectable, () => true);
});
rendered = await applicationBuilder.render();
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("checks for updates", () => {
expect(processCheckingForUpdatesMock).toHaveBeenCalled();
});
it("when just not enough time passes, does not check for updates again automatically yet", () => {
processCheckingForUpdatesMock.mockClear();
jest.advanceTimersByTime(ENOUGH_TIME - 1);
expect(processCheckingForUpdatesMock).not.toHaveBeenCalled();
});
it("when just enough time passes, checks for updates again automatically", () => {
processCheckingForUpdatesMock.mockClear();
jest.advanceTimersByTime(ENOUGH_TIME);
expect(processCheckingForUpdatesMock).toHaveBeenCalled();
});
});
describe("given updater is enabled but no configuration exist, when started", () => {
beforeEach(async () => {
applicationBuilder.beforeApplicationStart(({ mainDi }) => {
mainDi.override(electronUpdaterIsActiveInjectable, () => true);
mainDi.override(publishIsConfiguredInjectable, () => false);
});
await applicationBuilder.render();
});
it("does not check for updates", () => {
expect(processCheckingForUpdatesMock).not.toHaveBeenCalled();
});
it("when time passes, never checks for updates", () => {
jest.runOnlyPendingTimers();
expect(processCheckingForUpdatesMock).not.toHaveBeenCalled();
});
});
describe("given updater is not enabled but and configuration exist, when started", () => {
beforeEach(async () => {
applicationBuilder.beforeApplicationStart(({ mainDi }) => {
mainDi.override(electronUpdaterIsActiveInjectable, () => false);
mainDi.override(publishIsConfiguredInjectable, () => true);
});
await applicationBuilder.render();
});
it("does not check for updates", () => {
expect(processCheckingForUpdatesMock).not.toHaveBeenCalled();
});
it("when time passes, never checks for updates", () => {
jest.runOnlyPendingTimers();
expect(processCheckingForUpdatesMock).not.toHaveBeenCalled();
});
});
});
@@ -0,0 +1,331 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import quitAndInstallUpdateInjectable from "../../main/electron-app/features/quit-and-install-update.injectable";
import type { RenderResult } from "@testing-library/react";
import electronUpdaterIsActiveInjectable from "../../main/electron-app/features/electron-updater-is-active.injectable";
import publishIsConfiguredInjectable from "../../main/application-update/publish-is-configured.injectable";
import type { CheckForPlatformUpdates } from "../../main/application-update/check-for-platform-updates/check-for-platform-updates.injectable";
import checkForPlatformUpdatesInjectable from "../../main/application-update/check-for-platform-updates/check-for-platform-updates.injectable";
import type { AsyncFnMock } from "@async-fn/jest";
import asyncFn from "@async-fn/jest";
import type { UpdateChannel, UpdateChannelId } from "../../common/application-update/update-channels";
import { updateChannels } from "../../common/application-update/update-channels";
import type { DownloadPlatformUpdate } from "../../main/application-update/download-platform-update/download-platform-update.injectable";
import downloadPlatformUpdateInjectable from "../../main/application-update/download-platform-update/download-platform-update.injectable";
import selectedUpdateChannelInjectable from "../../common/application-update/selected-update-channel/selected-update-channel.injectable";
import type { IComputedValue } from "mobx";
import setUpdateOnQuitInjectable from "../../main/electron-app/features/set-update-on-quit.injectable";
import type { AskBoolean } from "../../main/ask-boolean/ask-boolean.injectable";
import askBooleanInjectable from "../../main/ask-boolean/ask-boolean.injectable";
import showInfoNotificationInjectable from "../../renderer/components/notifications/show-info-notification.injectable";
import processCheckingForUpdatesInjectable from "../../main/application-update/check-for-updates/process-checking-for-updates.injectable";
import appVersionInjectable from "../../common/get-configuration-file-model/app-version/app-version.injectable";
describe("selection of update stability", () => {
let applicationBuilder: ApplicationBuilder;
let quitAndInstallUpdateMock: jest.Mock;
let checkForPlatformUpdatesMock: AsyncFnMock<CheckForPlatformUpdates>;
let downloadPlatformUpdateMock: AsyncFnMock<DownloadPlatformUpdate>;
let setUpdateOnQuitMock: jest.Mock;
let showInfoNotificationMock: jest.Mock;
let askBooleanMock: AsyncFnMock<AskBoolean>;
beforeEach(() => {
applicationBuilder = getApplicationBuilder();
applicationBuilder.beforeApplicationStart(({ mainDi, rendererDi }) => {
quitAndInstallUpdateMock = jest.fn();
checkForPlatformUpdatesMock = asyncFn();
downloadPlatformUpdateMock = asyncFn();
setUpdateOnQuitMock = jest.fn();
showInfoNotificationMock = jest.fn(() => () => {});
askBooleanMock = asyncFn();
rendererDi.override(showInfoNotificationInjectable, () => showInfoNotificationMock);
mainDi.override(askBooleanInjectable, () => askBooleanMock);
mainDi.override(setUpdateOnQuitInjectable, () => setUpdateOnQuitMock);
mainDi.override(
checkForPlatformUpdatesInjectable,
() => checkForPlatformUpdatesMock,
);
mainDi.override(
downloadPlatformUpdateInjectable,
() => downloadPlatformUpdateMock,
);
mainDi.override(
quitAndInstallUpdateInjectable,
() => quitAndInstallUpdateMock,
);
mainDi.override(electronUpdaterIsActiveInjectable, () => true);
mainDi.override(publishIsConfiguredInjectable, () => true);
});
});
describe("when started", () => {
let rendered: RenderResult;
let processCheckingForUpdates: () => Promise<void>;
beforeEach(async () => {
rendered = await applicationBuilder.render();
processCheckingForUpdates = applicationBuilder.dis.mainDi.inject(processCheckingForUpdatesInjectable);
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
describe('given update channel "alpha" is selected, when checking for updates', () => {
let selectedUpdateChannel: {
value: IComputedValue<UpdateChannel>;
setValue: (channelId: UpdateChannelId) => void;
};
beforeEach(() => {
selectedUpdateChannel = applicationBuilder.dis.mainDi.inject(
selectedUpdateChannelInjectable,
);
selectedUpdateChannel.setValue(updateChannels.alpha.id);
processCheckingForUpdates();
});
it('checks updates from update channel "alpha"', () => {
expect(checkForPlatformUpdatesMock).toHaveBeenCalledWith(
updateChannels.alpha,
{ allowDowngrade: true },
);
});
it("when update is discovered, does not check update from other update channels", async () => {
checkForPlatformUpdatesMock.mockClear();
await checkForPlatformUpdatesMock.resolve({
updateWasDiscovered: true,
version: "some-version",
});
expect(checkForPlatformUpdatesMock).not.toHaveBeenCalled();
});
describe("when no update is discovered", () => {
beforeEach(async () => {
checkForPlatformUpdatesMock.mockClear();
await checkForPlatformUpdatesMock.resolve({
updateWasDiscovered: false,
});
});
it('checks updates from update channel "beta"', () => {
expect(checkForPlatformUpdatesMock).toHaveBeenCalledWith(
updateChannels.beta,
{ allowDowngrade: true },
);
});
it("when update is discovered, does not check update from other update channels", async () => {
checkForPlatformUpdatesMock.mockClear();
await checkForPlatformUpdatesMock.resolve({
updateWasDiscovered: true,
version: "some-version",
});
expect(checkForPlatformUpdatesMock).not.toHaveBeenCalled();
});
describe("when no update is discovered again", () => {
beforeEach(async () => {
checkForPlatformUpdatesMock.mockClear();
await checkForPlatformUpdatesMock.resolve({
updateWasDiscovered: false,
});
});
it('finally checks updates from update channel "latest"', () => {
expect(checkForPlatformUpdatesMock).toHaveBeenCalledWith(
updateChannels.latest,
{ allowDowngrade: true },
);
});
it("when update is discovered, does not check update from other update channels", async () => {
checkForPlatformUpdatesMock.mockClear();
await checkForPlatformUpdatesMock.resolve({
updateWasDiscovered: true,
version: "some-version",
});
expect(checkForPlatformUpdatesMock).not.toHaveBeenCalled();
});
});
});
});
describe('given update channel "beta" is selected', () => {
let selectedUpdateChannel: {
value: IComputedValue<UpdateChannel>;
setValue: (channelId: UpdateChannelId) => void;
};
beforeEach(() => {
selectedUpdateChannel = applicationBuilder.dis.mainDi.inject(
selectedUpdateChannelInjectable,
);
selectedUpdateChannel.setValue(updateChannels.beta.id);
});
describe("when checking for updates", () => {
beforeEach(() => {
processCheckingForUpdates();
});
describe('when update from "beta" channel is discovered', () => {
beforeEach(async () => {
await checkForPlatformUpdatesMock.resolve({
updateWasDiscovered: true,
version: "some-beta-version",
});
});
describe("when update is downloaded", () => {
beforeEach(async () => {
await downloadPlatformUpdateMock.resolve({ downloadWasSuccessful: true });
});
it("when user would close the application, installs the update", () => {
expect(setUpdateOnQuitMock).toHaveBeenLastCalledWith(true);
});
it('given user changes update channel to "latest", when user would close the application, does not install the update for not being stable enough', () => {
selectedUpdateChannel.setValue(updateChannels.latest.id);
expect(setUpdateOnQuitMock).toHaveBeenLastCalledWith(false);
});
it('given user changes update channel to "alpha", when user would close the application, installs the update for being stable enough', () => {
selectedUpdateChannel.setValue(updateChannels.alpha.id);
expect(setUpdateOnQuitMock).toHaveBeenLastCalledWith(false);
});
});
});
});
});
});
it("given valid update channel selection is stored, when checking for updates, checks for updates from the update channel", async () => {
applicationBuilder.beforeApplicationStart(({ mainDi }) => {
// TODO: Switch to more natural way of setting initial value
// TODO: UserStore is currently responsible for getting and setting initial value
const selectedUpdateChannel = mainDi.inject(selectedUpdateChannelInjectable);
selectedUpdateChannel.setValue(updateChannels.beta.id);
});
await applicationBuilder.render();
const processCheckingForUpdates = applicationBuilder.dis.mainDi.inject(processCheckingForUpdatesInjectable);
processCheckingForUpdates();
expect(checkForPlatformUpdatesMock).toHaveBeenCalledWith(updateChannels.beta, expect.any(Object));
});
it("given invalid update channel selection is stored, when checking for updates, checks for updates from the update channel", async () => {
applicationBuilder.beforeApplicationStart(({ mainDi }) => {
// TODO: Switch to more natural way of setting initial value
// TODO: UserStore is currently responsible for getting and setting initial value
const selectedUpdateChannel = mainDi.inject(selectedUpdateChannelInjectable);
selectedUpdateChannel.setValue("something-invalid" as UpdateChannelId);
});
await applicationBuilder.render();
const processCheckingForUpdates = applicationBuilder.dis.mainDi.inject(processCheckingForUpdatesInjectable);
processCheckingForUpdates();
expect(checkForPlatformUpdatesMock).toHaveBeenCalledWith(updateChannels.latest, expect.any(Object));
});
it('given no update channel selection is stored and currently using stable release, when user checks for updates, checks for updates from "latest" update channel by default', async () => {
applicationBuilder.beforeApplicationStart(({ mainDi }) => {
mainDi.override(appVersionInjectable, () => "1.0.0");
});
await applicationBuilder.render();
const processCheckingForUpdates = applicationBuilder.dis.mainDi.inject(processCheckingForUpdatesInjectable);
processCheckingForUpdates();
expect(checkForPlatformUpdatesMock).toHaveBeenCalledWith(
updateChannels.latest,
{ allowDowngrade: true },
);
});
it('given no update channel selection is stored and currently using alpha release, when checking for updates, checks for updates from "alpha" channel', async () => {
applicationBuilder.beforeApplicationStart(({ mainDi }) => {
mainDi.override(appVersionInjectable, () => "1.0.0-alpha");
});
await applicationBuilder.render();
const processCheckingForUpdates = applicationBuilder.dis.mainDi.inject(processCheckingForUpdatesInjectable);
processCheckingForUpdates();
expect(checkForPlatformUpdatesMock).toHaveBeenCalledWith(updateChannels.alpha, expect.any(Object));
});
it('given no update channel selection is stored and currently using beta release, when checking for updates, checks for updates from "beta" channel', async () => {
applicationBuilder.beforeApplicationStart(({ mainDi }) => {
mainDi.override(appVersionInjectable, () => "1.0.0-beta");
});
await applicationBuilder.render();
const processCheckingForUpdates = applicationBuilder.dis.mainDi.inject(processCheckingForUpdatesInjectable);
processCheckingForUpdates();
expect(checkForPlatformUpdatesMock).toHaveBeenCalledWith(updateChannels.beta, expect.any(Object));
});
it("given update channel selection is stored and currently using prerelease, when checking for updates, checks for updates from stored channel", async () => {
applicationBuilder.beforeApplicationStart(({ mainDi }) => {
mainDi.override(appVersionInjectable, () => "1.0.0-alpha");
// TODO: Switch to more natural way of setting initial value
// TODO: UserStore is currently responsible for getting and setting initial value
const selectedUpdateChannel = mainDi.inject(selectedUpdateChannelInjectable);
selectedUpdateChannel.setValue(updateChannels.beta.id);
});
await applicationBuilder.render();
const processCheckingForUpdates = applicationBuilder.dis.mainDi.inject(processCheckingForUpdatesInjectable);
processCheckingForUpdates();
expect(checkForPlatformUpdatesMock).toHaveBeenCalledWith(updateChannels.beta, expect.any(Object));
});
});
@@ -328,6 +328,9 @@ exports[`cluster - order of sidebar items when rendered renders 1`] = `
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -723,5 +726,8 @@ exports[`cluster - order of sidebar items when rendered when parent is expanded
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -293,6 +293,9 @@ exports[`cluster - sidebar and tab navigation for core given core registrations
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -589,6 +592,9 @@ exports[`cluster - sidebar and tab navigation for core given core registrations
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -909,6 +915,9 @@ exports[`cluster - sidebar and tab navigation for core given core registrations
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -1234,6 +1243,9 @@ exports[`cluster - sidebar and tab navigation for core given core registrations
<div
data-testid="some-child-page"
/>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -1534,6 +1546,9 @@ exports[`cluster - sidebar and tab navigation for core given core registrations
<div
data-testid="some-child-page"
/>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -1854,6 +1869,9 @@ exports[`cluster - sidebar and tab navigation for core given core registrations
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -2150,5 +2168,8 @@ exports[`cluster - sidebar and tab navigation for core given core registrations
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -293,6 +293,9 @@ exports[`cluster - sidebar and tab navigation for extensions given extension wit
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -589,6 +592,9 @@ exports[`cluster - sidebar and tab navigation for extensions given extension wit
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -929,6 +935,9 @@ exports[`cluster - sidebar and tab navigation for extensions given extension wit
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -1313,6 +1322,9 @@ exports[`cluster - sidebar and tab navigation for extensions given extension wit
</div>
</main>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -1697,6 +1709,9 @@ exports[`cluster - sidebar and tab navigation for extensions given extension wit
</div>
</main>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -2036,6 +2051,9 @@ exports[`cluster - sidebar and tab navigation for extensions given extension wit
</div>
</main>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -2376,6 +2394,9 @@ exports[`cluster - sidebar and tab navigation for extensions given extension wit
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -2672,5 +2693,8 @@ exports[`cluster - sidebar and tab navigation for extensions given extension wit
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -261,6 +261,9 @@ exports[`cluster - visibility of sidebar items given kube resource for route is
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -573,5 +576,8 @@ exports[`cluster - visibility of sidebar items given kube resource for route is
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -1,6 +1,12 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`extensions - navigation using application menu renders 1`] = `<div />`;
exports[`extensions - navigation using application menu renders 1`] = `
<div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
exports[`extensions - navigation using application menu when navigating to extensions using application menu renders 1`] = `
<div>
@@ -118,5 +124,8 @@ exports[`extensions - navigation using application menu when navigating to exten
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -6,12 +6,7 @@
import type { RenderResult } from "@testing-library/react";
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import isAutoUpdateEnabledInjectable from "../../main/is-auto-update-enabled.injectable";
import extensionsStoreInjectable from "../../extensions/extensions-store/extensions-store.injectable";
import type { ExtensionsStore } from "../../extensions/extensions-store/extensions-store";
import fileSystemProvisionerStoreInjectable from "../../extensions/extension-loader/file-system-provisioner-store/file-system-provisioner-store.injectable";
import type { FileSystemProvisionerStore } from "../../extensions/extension-loader/file-system-provisioner-store/file-system-provisioner-store";
import focusWindowInjectable from "../../renderer/ipc-channel-listeners/focus-window.injectable";
import focusWindowInjectable from "../../renderer/navigation/focus-window.injectable";
// TODO: Make components free of side effects by making them deterministic
jest.mock("../../renderer/components/input/input");
@@ -22,11 +17,7 @@ describe("extensions - navigation using application menu", () => {
let focusWindowMock: jest.Mock;
beforeEach(async () => {
applicationBuilder = getApplicationBuilder().beforeApplicationStart(({ mainDi, rendererDi }) => {
mainDi.override(isAutoUpdateEnabledInjectable, () => () => false);
rendererDi.override(extensionsStoreInjectable, () => ({}) as unknown as ExtensionsStore);
rendererDi.override(fileSystemProvisionerStoreInjectable, () => ({}) as unknown as FileSystemProvisionerStore);
applicationBuilder = getApplicationBuilder().beforeApplicationStart(({ rendererDi }) => {
focusWindowMock = jest.fn();
rendererDi.override(focusWindowInjectable, () => focusWindowMock);
@@ -454,5 +454,8 @@ exports[`helm-charts - navigation to Helm charts when navigating to Helm charts
</div>
</main>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -356,13 +356,12 @@ exports[`preferences - closing-preferences given accessing preferences directly
class="Select__control css-1s2u09g-control"
>
<div
class="Select__value-container css-319lph-ValueContainer"
class="Select__value-container Select__value-container--has-value css-319lph-ValueContainer"
>
<div
class="Select__placeholder css-14el2xx-placeholder"
id="react-select-update-channel-input-placeholder"
class="Select__single-value css-qc6sy-singleValue"
>
Select...
Stable
</div>
<div
class="Select__input-container css-6j8wv5-Input"
@@ -370,7 +369,6 @@ exports[`preferences - closing-preferences given accessing preferences directly
>
<input
aria-autocomplete="list"
aria-describedby="react-select-update-channel-input-placeholder"
aria-expanded="false"
aria-haspopup="true"
autocapitalize="none"
@@ -537,6 +535,9 @@ exports[`preferences - closing-preferences given accessing preferences directly
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -679,6 +680,9 @@ exports[`preferences - closing-preferences given accessing preferences directly
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -687,6 +691,9 @@ exports[`preferences - closing-preferences given accessing preferences directly
<div>
Some front page
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -695,6 +702,9 @@ exports[`preferences - closing-preferences given accessing preferences directly
<div>
Some front page
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -1054,13 +1064,12 @@ exports[`preferences - closing-preferences given already in a page and then navi
class="Select__control css-1s2u09g-control"
>
<div
class="Select__value-container css-319lph-ValueContainer"
class="Select__value-container Select__value-container--has-value css-319lph-ValueContainer"
>
<div
class="Select__placeholder css-14el2xx-placeholder"
id="react-select-update-channel-input-placeholder"
class="Select__single-value css-qc6sy-singleValue"
>
Select...
Stable
</div>
<div
class="Select__input-container css-6j8wv5-Input"
@@ -1068,7 +1077,6 @@ exports[`preferences - closing-preferences given already in a page and then navi
>
<input
aria-autocomplete="list"
aria-describedby="react-select-update-channel-input-placeholder"
aria-expanded="false"
aria-haspopup="true"
autocapitalize="none"
@@ -1235,6 +1243,9 @@ exports[`preferences - closing-preferences given already in a page and then navi
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -1377,6 +1388,9 @@ exports[`preferences - closing-preferences given already in a page and then navi
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -1519,6 +1533,9 @@ exports[`preferences - closing-preferences given already in a page and then navi
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -1661,5 +1678,8 @@ exports[`preferences - closing-preferences given already in a page and then navi
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -199,6 +199,9 @@ exports[`preferences - navigation to application preferences given in some child
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -546,13 +549,12 @@ exports[`preferences - navigation to application preferences given in some child
class="Select__control css-1s2u09g-control"
>
<div
class="Select__value-container css-319lph-ValueContainer"
class="Select__value-container Select__value-container--has-value css-319lph-ValueContainer"
>
<div
class="Select__placeholder css-14el2xx-placeholder"
id="react-select-update-channel-input-placeholder"
class="Select__single-value css-qc6sy-singleValue"
>
Select...
Stable
</div>
<div
class="Select__input-container css-6j8wv5-Input"
@@ -560,7 +562,6 @@ exports[`preferences - navigation to application preferences given in some child
>
<input
aria-autocomplete="list"
aria-describedby="react-select-update-channel-input-placeholder"
aria-expanded="false"
aria-haspopup="true"
autocapitalize="none"
@@ -727,5 +728,8 @@ exports[`preferences - navigation to application preferences given in some child
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -344,13 +344,12 @@ exports[`preferences - navigation to editor preferences given in preferences, wh
class="Select__control css-1s2u09g-control"
>
<div
class="Select__value-container css-319lph-ValueContainer"
class="Select__value-container Select__value-container--has-value css-319lph-ValueContainer"
>
<div
class="Select__placeholder css-14el2xx-placeholder"
id="react-select-update-channel-input-placeholder"
class="Select__single-value css-qc6sy-singleValue"
>
Select...
Stable
</div>
<div
class="Select__input-container css-6j8wv5-Input"
@@ -358,7 +357,6 @@ exports[`preferences - navigation to editor preferences given in preferences, wh
>
<input
aria-autocomplete="list"
aria-describedby="react-select-update-channel-input-placeholder"
aria-expanded="false"
aria-haspopup="true"
autocapitalize="none"
@@ -525,6 +523,9 @@ exports[`preferences - navigation to editor preferences given in preferences, wh
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -935,5 +936,8 @@ exports[`preferences - navigation to editor preferences given in preferences, wh
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -344,13 +344,12 @@ exports[`preferences - navigation to extension specific preferences given in pre
class="Select__control css-1s2u09g-control"
>
<div
class="Select__value-container css-319lph-ValueContainer"
class="Select__value-container Select__value-container--has-value css-319lph-ValueContainer"
>
<div
class="Select__placeholder css-14el2xx-placeholder"
id="react-select-update-channel-input-placeholder"
class="Select__single-value css-qc6sy-singleValue"
>
Select...
Stable
</div>
<div
class="Select__input-container css-6j8wv5-Input"
@@ -358,7 +357,6 @@ exports[`preferences - navigation to extension specific preferences given in pre
>
<input
aria-autocomplete="list"
aria-describedby="react-select-update-channel-input-placeholder"
aria-expanded="false"
aria-haspopup="true"
autocapitalize="none"
@@ -525,6 +523,9 @@ exports[`preferences - navigation to extension specific preferences given in pre
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -884,13 +885,12 @@ exports[`preferences - navigation to extension specific preferences given in pre
class="Select__control css-1s2u09g-control"
>
<div
class="Select__value-container css-319lph-ValueContainer"
class="Select__value-container Select__value-container--has-value css-319lph-ValueContainer"
>
<div
class="Select__placeholder css-14el2xx-placeholder"
id="react-select-update-channel-input-placeholder"
class="Select__single-value css-qc6sy-singleValue"
>
Select...
Stable
</div>
<div
class="Select__input-container css-6j8wv5-Input"
@@ -898,7 +898,6 @@ exports[`preferences - navigation to extension specific preferences given in pre
>
<input
aria-autocomplete="list"
aria-describedby="react-select-update-channel-input-placeholder"
aria-expanded="false"
aria-haspopup="true"
autocapitalize="none"
@@ -1065,6 +1064,9 @@ exports[`preferences - navigation to extension specific preferences given in pre
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -1239,5 +1241,8 @@ exports[`preferences - navigation to extension specific preferences given in pre
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -344,13 +344,12 @@ exports[`preferences - navigation to kubernetes preferences given in preferences
class="Select__control css-1s2u09g-control"
>
<div
class="Select__value-container css-319lph-ValueContainer"
class="Select__value-container Select__value-container--has-value css-319lph-ValueContainer"
>
<div
class="Select__placeholder css-14el2xx-placeholder"
id="react-select-update-channel-input-placeholder"
class="Select__single-value css-qc6sy-singleValue"
>
Select...
Stable
</div>
<div
class="Select__input-container css-6j8wv5-Input"
@@ -358,7 +357,6 @@ exports[`preferences - navigation to kubernetes preferences given in preferences
>
<input
aria-autocomplete="list"
aria-describedby="react-select-update-channel-input-placeholder"
aria-expanded="false"
aria-haspopup="true"
autocapitalize="none"
@@ -525,6 +523,9 @@ exports[`preferences - navigation to kubernetes preferences given in preferences
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -836,7 +837,7 @@ exports[`preferences - navigation to kubernetes preferences given in preferences
class="flex gaps"
>
<div
class="Select theme-lens box grow css-b62m3t-container"
class="Select theme-lens box grow Select--is-disabled css-3iigni-container"
>
<span
class="css-1f43avz-a11yText-A11yText"
@@ -849,7 +850,7 @@ exports[`preferences - navigation to kubernetes preferences given in preferences
class="css-1f43avz-a11yText-A11yText"
/>
<div
class="Select__control css-1s2u09g-control"
class="Select__control Select__control--is-disabled css-1insrsq-control"
>
<div
class="Select__value-container css-319lph-ValueContainer"
@@ -861,7 +862,7 @@ exports[`preferences - navigation to kubernetes preferences given in preferences
Repositories
</div>
<div
class="Select__input-container css-6j8wv5-Input"
class="Select__input-container css-jzldcf-Input"
data-value=""
>
<input
@@ -873,6 +874,7 @@ exports[`preferences - navigation to kubernetes preferences given in preferences
autocomplete="off"
autocorrect="off"
class="Select__input"
disabled=""
id="HelmRepoSelect"
role="combobox"
spellcheck="false"
@@ -886,8 +888,22 @@ exports[`preferences - navigation to kubernetes preferences given in preferences
<div
class="Select__indicators css-1hb7zxy-IndicatorsContainer"
>
<div
aria-hidden="true"
class="Select__indicator Select__loading-indicator css-at12u2-loadingIndicator"
>
<span
class="css-1xtdfmb-LoadingDot"
/>
<span
class="css-zoievk-LoadingDot"
/>
<span
class="css-x748d8-LoadingDot"
/>
</div>
<span
class="Select__indicator-separator css-1okebmr-indicatorSeparator"
class="Select__indicator-separator css-109onse-indicatorSeparator"
/>
<div
aria-hidden="true"
@@ -920,13 +936,11 @@ exports[`preferences - navigation to kubernetes preferences given in preferences
class="repos"
>
<div
class="notice"
class="pt-5 relative"
>
<div
class="flex-grow text-center"
>
The repositories have not been added yet
</div>
class="Spinner singleColor center"
/>
</div>
</div>
</div>
@@ -969,5 +983,8 @@ exports[`preferences - navigation to kubernetes preferences given in preferences
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -344,13 +344,12 @@ exports[`preferences - navigation to proxy preferences given in preferences, whe
class="Select__control css-1s2u09g-control"
>
<div
class="Select__value-container css-319lph-ValueContainer"
class="Select__value-container Select__value-container--has-value css-319lph-ValueContainer"
>
<div
class="Select__placeholder css-14el2xx-placeholder"
id="react-select-update-channel-input-placeholder"
class="Select__single-value css-qc6sy-singleValue"
>
Select...
Stable
</div>
<div
class="Select__input-container css-6j8wv5-Input"
@@ -358,7 +357,6 @@ exports[`preferences - navigation to proxy preferences given in preferences, whe
>
<input
aria-autocomplete="list"
aria-describedby="react-select-update-channel-input-placeholder"
aria-expanded="false"
aria-haspopup="true"
autocapitalize="none"
@@ -525,6 +523,9 @@ exports[`preferences - navigation to proxy preferences given in preferences, whe
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -727,5 +728,8 @@ exports[`preferences - navigation to proxy preferences given in preferences, whe
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -185,6 +185,9 @@ exports[`preferences - navigation to telemetry preferences given URL for Sentry
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -532,13 +535,12 @@ exports[`preferences - navigation to telemetry preferences given in preferences,
class="Select__control css-1s2u09g-control"
>
<div
class="Select__value-container css-319lph-ValueContainer"
class="Select__value-container Select__value-container--has-value css-319lph-ValueContainer"
>
<div
class="Select__placeholder css-14el2xx-placeholder"
id="react-select-update-channel-input-placeholder"
class="Select__single-value css-qc6sy-singleValue"
>
Select...
Stable
</div>
<div
class="Select__input-container css-6j8wv5-Input"
@@ -546,7 +548,6 @@ exports[`preferences - navigation to telemetry preferences given in preferences,
>
<input
aria-autocomplete="list"
aria-describedby="react-select-update-channel-input-placeholder"
aria-expanded="false"
aria-haspopup="true"
autocapitalize="none"
@@ -713,6 +714,9 @@ exports[`preferences - navigation to telemetry preferences given in preferences,
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -1072,13 +1076,12 @@ exports[`preferences - navigation to telemetry preferences given in preferences,
class="Select__control css-1s2u09g-control"
>
<div
class="Select__value-container css-319lph-ValueContainer"
class="Select__value-container Select__value-container--has-value css-319lph-ValueContainer"
>
<div
class="Select__placeholder css-14el2xx-placeholder"
id="react-select-update-channel-input-placeholder"
class="Select__single-value css-qc6sy-singleValue"
>
Select...
Stable
</div>
<div
class="Select__input-container css-6j8wv5-Input"
@@ -1086,7 +1089,6 @@ exports[`preferences - navigation to telemetry preferences given in preferences,
>
<input
aria-autocomplete="list"
aria-describedby="react-select-update-channel-input-placeholder"
aria-expanded="false"
aria-haspopup="true"
autocapitalize="none"
@@ -1253,6 +1255,9 @@ exports[`preferences - navigation to telemetry preferences given in preferences,
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -1429,6 +1434,9 @@ exports[`preferences - navigation to telemetry preferences given in preferences,
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -1568,5 +1576,8 @@ exports[`preferences - navigation to telemetry preferences given no URL for Sent
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -344,13 +344,12 @@ exports[`preferences - navigation to terminal preferences given in preferences,
class="Select__control css-1s2u09g-control"
>
<div
class="Select__value-container css-319lph-ValueContainer"
class="Select__value-container Select__value-container--has-value css-319lph-ValueContainer"
>
<div
class="Select__placeholder css-14el2xx-placeholder"
id="react-select-update-channel-input-placeholder"
class="Select__single-value css-qc6sy-singleValue"
>
Select...
Stable
</div>
<div
class="Select__input-container css-6j8wv5-Input"
@@ -358,7 +357,6 @@ exports[`preferences - navigation to terminal preferences given in preferences,
>
<input
aria-autocomplete="list"
aria-describedby="react-select-update-channel-input-placeholder"
aria-expanded="false"
aria-haspopup="true"
autocapitalize="none"
@@ -525,6 +523,9 @@ exports[`preferences - navigation to terminal preferences given in preferences,
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -845,5 +846,8 @@ exports[`preferences - navigation to terminal preferences given in preferences,
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -1,6 +1,12 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`preferences - navigation using application menu renders 1`] = `<div />`;
exports[`preferences - navigation using application menu renders 1`] = `
<div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
exports[`preferences - navigation using application menu when navigating to preferences using application menu renders 1`] = `
<div>
@@ -346,13 +352,12 @@ exports[`preferences - navigation using application menu when navigating to pref
class="Select__control css-1s2u09g-control"
>
<div
class="Select__value-container css-319lph-ValueContainer"
class="Select__value-container Select__value-container--has-value css-319lph-ValueContainer"
>
<div
class="Select__placeholder css-14el2xx-placeholder"
id="react-select-update-channel-input-placeholder"
class="Select__single-value css-qc6sy-singleValue"
>
Select...
Stable
</div>
<div
class="Select__input-container css-6j8wv5-Input"
@@ -360,7 +365,6 @@ exports[`preferences - navigation using application menu when navigating to pref
>
<input
aria-autocomplete="list"
aria-describedby="react-select-update-channel-input-placeholder"
aria-expanded="false"
aria-haspopup="true"
autocapitalize="none"
@@ -527,5 +531,8 @@ exports[`preferences - navigation using application menu when navigating to pref
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -0,0 +1,542 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`show-about-using-tray renders 1`] = `
<body>
<div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
</body>
`;
exports[`show-about-using-tray when navigating using tray renders 1`] = `
<body>
<div>
<div
class="SettingLayout showNavigation Preferences"
data-testid="application-preferences-page"
>
<nav
class="sidebarRegion"
>
<div
class="sidebar"
>
<div
class="Tabs flex column"
>
<div
class="header"
>
Preferences
</div>
<div
class="Tab flex gaps align-center active"
data-testid="tab-link-for-application"
role="tab"
tabindex="0"
>
<div
class="label"
>
App
</div>
</div>
<div
class="Tab flex gaps align-center"
data-testid="tab-link-for-proxy"
role="tab"
tabindex="0"
>
<div
class="label"
>
Proxy
</div>
</div>
<div
class="Tab flex gaps align-center"
data-testid="tab-link-for-kubernetes"
role="tab"
tabindex="0"
>
<div
class="label"
>
Kubernetes
</div>
</div>
<div
class="Tab flex gaps align-center"
data-testid="tab-link-for-editor"
role="tab"
tabindex="0"
>
<div
class="label"
>
Editor
</div>
</div>
<div
class="Tab flex gaps align-center"
data-testid="tab-link-for-terminal"
role="tab"
tabindex="0"
>
<div
class="label"
>
Terminal
</div>
</div>
</div>
</div>
</nav>
<div
class="contentRegion"
id="ScrollSpyRoot"
>
<div
class="content"
>
<section
id="application"
>
<h2
data-testid="application-header"
>
Application
</h2>
<section
id="appearance"
>
<div
class="SubTitle"
>
Theme
</div>
<div
class="Select theme-lens css-b62m3t-container"
>
<span
class="css-1f43avz-a11yText-A11yText"
id="react-select-theme-input-live-region"
/>
<span
aria-atomic="false"
aria-live="polite"
aria-relevant="additions text"
class="css-1f43avz-a11yText-A11yText"
/>
<div
class="Select__control css-1s2u09g-control"
>
<div
class="Select__value-container css-319lph-ValueContainer"
>
<div
class="Select__placeholder css-14el2xx-placeholder"
id="react-select-theme-input-placeholder"
>
Select...
</div>
<div
class="Select__input-container css-6j8wv5-Input"
data-value=""
>
<input
aria-autocomplete="list"
aria-describedby="react-select-theme-input-placeholder"
aria-expanded="false"
aria-haspopup="true"
autocapitalize="none"
autocomplete="off"
autocorrect="off"
class="Select__input"
id="theme-input"
role="combobox"
spellcheck="false"
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
/>
</div>
</div>
<div
class="Select__indicators css-1hb7zxy-IndicatorsContainer"
>
<span
class="Select__indicator-separator css-1okebmr-indicatorSeparator"
/>
<div
aria-hidden="true"
class="Select__indicator Select__dropdown-indicator css-tlfecz-indicatorContainer"
>
<svg
aria-hidden="true"
class="css-tj5bde-Svg"
focusable="false"
height="20"
viewBox="0 0 20 20"
width="20"
>
<path
d="M4.516 7.548c0.436-0.446 1.043-0.481 1.576 0l3.908 3.747 3.908-3.747c0.533-0.481 1.141-0.446 1.574 0 0.436 0.445 0.408 1.197 0 1.615-0.406 0.418-4.695 4.502-4.695 4.502-0.217 0.223-0.502 0.335-0.787 0.335s-0.57-0.112-0.789-0.335c0 0-4.287-4.084-4.695-4.502s-0.436-1.17 0-1.615z"
/>
</svg>
</div>
</div>
</div>
</div>
</section>
<hr />
<section
id="extensionRegistryUrl"
>
<div
class="SubTitle"
>
Extension Install Registry
</div>
<div
class="Select theme-lens css-b62m3t-container"
>
<span
class="css-1f43avz-a11yText-A11yText"
id="react-select-extension-install-registry-input-live-region"
/>
<span
aria-atomic="false"
aria-live="polite"
aria-relevant="additions text"
class="css-1f43avz-a11yText-A11yText"
/>
<div
class="Select__control css-1s2u09g-control"
>
<div
class="Select__value-container css-319lph-ValueContainer"
>
<div
class="Select__placeholder css-14el2xx-placeholder"
id="react-select-extension-install-registry-input-placeholder"
>
Select...
</div>
<div
class="Select__input-container css-6j8wv5-Input"
data-value=""
>
<input
aria-autocomplete="list"
aria-describedby="react-select-extension-install-registry-input-placeholder"
aria-expanded="false"
aria-haspopup="true"
autocapitalize="none"
autocomplete="off"
autocorrect="off"
class="Select__input"
id="extension-install-registry-input"
role="combobox"
spellcheck="false"
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
/>
</div>
</div>
<div
class="Select__indicators css-1hb7zxy-IndicatorsContainer"
>
<span
class="Select__indicator-separator css-1okebmr-indicatorSeparator"
/>
<div
aria-hidden="true"
class="Select__indicator Select__dropdown-indicator css-tlfecz-indicatorContainer"
>
<svg
aria-hidden="true"
class="css-tj5bde-Svg"
focusable="false"
height="20"
viewBox="0 0 20 20"
width="20"
>
<path
d="M4.516 7.548c0.436-0.446 1.043-0.481 1.576 0l3.908 3.747 3.908-3.747c0.533-0.481 1.141-0.446 1.574 0 0.436 0.445 0.408 1.197 0 1.615-0.406 0.418-4.695 4.502-4.695 4.502-0.217 0.223-0.502 0.335-0.787 0.335s-0.57-0.112-0.789-0.335c0 0-4.287-4.084-4.695-4.502s-0.436-1.17 0-1.615z"
/>
</svg>
</div>
</div>
</div>
</div>
<p
class="mt-4 mb-5 leading-relaxed"
>
This setting is to change the registry URL for installing extensions by name.
If you are unable to access the default registry (https://registry.npmjs.org) you can change it in your
<b>
.npmrc
</b>
file or in the input below.
</p>
<div
class="Input theme round black disabled invalid"
>
<label
class="input-area flex gaps align-center"
id=""
>
<input
class="input box grow"
disabled=""
placeholder="Custom Extension Registry URL..."
spellcheck="false"
value="some-custom-url"
/>
</label>
<div
class="input-info flex gaps"
/>
</div>
</section>
<hr />
<section
id="other"
>
<div
class="SubTitle"
>
Start-up
</div>
<label
class="Switch"
data-testid="switch"
>
Automatically start Lens on login
<input
role="switch"
type="checkbox"
/>
</label>
</section>
<hr />
<section
id="update-channel"
>
<div
class="SubTitle"
>
Update Channel
</div>
<div
class="Select theme-lens css-b62m3t-container"
>
<span
class="css-1f43avz-a11yText-A11yText"
id="react-select-update-channel-input-live-region"
/>
<span
aria-atomic="false"
aria-live="polite"
aria-relevant="additions text"
class="css-1f43avz-a11yText-A11yText"
/>
<div
class="Select__control css-1s2u09g-control"
>
<div
class="Select__value-container Select__value-container--has-value css-319lph-ValueContainer"
>
<div
class="Select__single-value css-qc6sy-singleValue"
>
Stable
</div>
<div
class="Select__input-container css-6j8wv5-Input"
data-value=""
>
<input
aria-autocomplete="list"
aria-expanded="false"
aria-haspopup="true"
autocapitalize="none"
autocomplete="off"
autocorrect="off"
class="Select__input"
id="update-channel-input"
role="combobox"
spellcheck="false"
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
/>
</div>
</div>
<div
class="Select__indicators css-1hb7zxy-IndicatorsContainer"
>
<span
class="Select__indicator-separator css-1okebmr-indicatorSeparator"
/>
<div
aria-hidden="true"
class="Select__indicator Select__dropdown-indicator css-tlfecz-indicatorContainer"
>
<svg
aria-hidden="true"
class="css-tj5bde-Svg"
focusable="false"
height="20"
viewBox="0 0 20 20"
width="20"
>
<path
d="M4.516 7.548c0.436-0.446 1.043-0.481 1.576 0l3.908 3.747 3.908-3.747c0.533-0.481 1.141-0.446 1.574 0 0.436 0.445 0.408 1.197 0 1.615-0.406 0.418-4.695 4.502-4.695 4.502-0.217 0.223-0.502 0.335-0.787 0.335s-0.57-0.112-0.789-0.335c0 0-4.287-4.084-4.695-4.502s-0.436-1.17 0-1.615z"
/>
</svg>
</div>
</div>
</div>
</div>
</section>
<hr />
<section
id="locale"
>
<div
class="SubTitle"
>
Locale Timezone
</div>
<div
class="Select theme-lens css-b62m3t-container"
>
<span
class="css-1f43avz-a11yText-A11yText"
id="react-select-timezone-input-live-region"
/>
<span
aria-atomic="false"
aria-live="polite"
aria-relevant="additions text"
class="css-1f43avz-a11yText-A11yText"
/>
<div
class="Select__control css-1s2u09g-control"
>
<div
class="Select__value-container css-319lph-ValueContainer"
>
<div
class="Select__placeholder css-14el2xx-placeholder"
id="react-select-timezone-input-placeholder"
>
Select...
</div>
<div
class="Select__input-container css-6j8wv5-Input"
data-value=""
>
<input
aria-autocomplete="list"
aria-describedby="react-select-timezone-input-placeholder"
aria-expanded="false"
aria-haspopup="true"
autocapitalize="none"
autocomplete="off"
autocorrect="off"
class="Select__input"
id="timezone-input"
role="combobox"
spellcheck="false"
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
/>
</div>
</div>
<div
class="Select__indicators css-1hb7zxy-IndicatorsContainer"
>
<span
class="Select__indicator-separator css-1okebmr-indicatorSeparator"
/>
<div
aria-hidden="true"
class="Select__indicator Select__dropdown-indicator css-tlfecz-indicatorContainer"
>
<svg
aria-hidden="true"
class="css-tj5bde-Svg"
focusable="false"
height="20"
viewBox="0 0 20 20"
width="20"
>
<path
d="M4.516 7.548c0.436-0.446 1.043-0.481 1.576 0l3.908 3.747 3.908-3.747c0.533-0.481 1.141-0.446 1.574 0 0.436 0.445 0.408 1.197 0 1.615-0.406 0.418-4.695 4.502-4.695 4.502-0.217 0.223-0.502 0.335-0.787 0.335s-0.57-0.112-0.789-0.335c0 0-4.287-4.084-4.695-4.502s-0.436-1.17 0-1.615z"
/>
</svg>
</div>
</div>
</div>
</div>
</section>
</section>
</div>
<div
class="toolsRegion"
>
<div
class="fixed top-[60px]"
>
<div
data-testid="close-preferences"
>
<div
aria-label="Close"
class="closeButton"
role="button"
>
<i
class="Icon icon material focusable"
>
<span
class="icon"
data-icon-name="close"
>
close
</span>
</i>
</div>
<div
aria-hidden="true"
class="esc"
>
ESC
</div>
</div>
</div>
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
</body>
`;
@@ -5,17 +5,12 @@
import type { RenderResult } from "@testing-library/react";
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import defaultShellInjectable from "../../renderer/components/+preferences/default-shell.injectable";
describe("preferences - navigation to terminal preferences", () => {
let applicationBuilder: ApplicationBuilder;
beforeEach(() => {
applicationBuilder = getApplicationBuilder();
applicationBuilder.beforeApplicationStart(({ rendererDi }) => {
rendererDi.override(defaultShellInjectable, () => "some-default-shell");
});
});
describe("given in preferences, when rendered", () => {
@@ -0,0 +1,44 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { RenderResult } from "@testing-library/react";
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
describe("show-about-using-tray", () => {
let applicationBuilder: ApplicationBuilder;
let rendered: RenderResult;
beforeEach(async () => {
applicationBuilder = getApplicationBuilder();
rendered = await applicationBuilder.render();
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("does not show application preferences page yet", () => {
const actual = rendered.queryByTestId("application-preferences-page");
expect(actual).toBeNull();
});
describe("when navigating using tray", () => {
beforeEach(async () => {
await applicationBuilder.tray.click("open-preferences");
});
it("renders", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
it("shows application preferences page", () => {
const actual = rendered.getByTestId("application-preferences-page");
expect(actual).not.toBeNull();
});
});
});
@@ -1,6 +1,12 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`welcome - navigation using application menu renders 1`] = `<div />`;
exports[`welcome - navigation using application menu renders 1`] = `
<div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
exports[`welcome - navigation using application menu when navigating to welcome using application menu renders 1`] = `
<div>
@@ -87,5 +93,8 @@ exports[`welcome - navigation using application menu when navigating to welcome
</div>
</div>
</div>
<div
class="Notifications flex column align-flex-end"
/>
</div>
`;
@@ -6,16 +6,13 @@
import type { RenderResult } from "@testing-library/react";
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import isAutoUpdateEnabledInjectable from "../../main/is-auto-update-enabled.injectable";
describe("welcome - navigation using application menu", () => {
let applicationBuilder: ApplicationBuilder;
let rendered: RenderResult;
beforeEach(async () => {
applicationBuilder = getApplicationBuilder().beforeApplicationStart(({ mainDi }) => {
mainDi.override(isAutoUpdateEnabledInjectable, () => () => false);
});
applicationBuilder = getApplicationBuilder();
rendered = await applicationBuilder.render();
});