diff --git a/.appveyor.yml b/.appveyor.yml index ce8c6b8e..e847a8de 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -15,7 +15,7 @@ init: install: - ps: Install-Product node 8 x64 - - yarn + - yarn install build_script: - yarn buildforelectron @@ -28,7 +28,7 @@ build_script: test: off artifacts: - - path: 'GNS3*.exe' + - path: 'gns3-web-ui*.exe' name: gns3-web-ui environment: diff --git a/angular.json b/angular.json index 2a7f2484..f4430c7a 100644 --- a/angular.json +++ b/angular.json @@ -22,6 +22,7 @@ ], "styles": [ "node_modules/bootstrap/dist/css/bootstrap.min.css", + "node_modules/notosans-fontface/css/notosans-fontface.min.css", "src/styles.css", "src/theme.scss" ], @@ -125,6 +126,7 @@ "scripts": [], "styles": [ "node_modules/bootstrap/dist/css/bootstrap.min.css", + "node_modules/notosans-fontface/css/notosans-fontface.min.css", "src/styles.css", "src/theme.scss" ], @@ -184,4 +186,4 @@ "prefix": "app" } } -} \ No newline at end of file +} diff --git a/e2e/app.e2e-spec.ts b/e2e/app.e2e-spec.ts index 20f85005..40a0b075 100644 --- a/e2e/app.e2e-spec.ts +++ b/e2e/app.e2e-spec.ts @@ -9,6 +9,6 @@ describe('gns3-web-ui App', () => { it('should display title', () => { page.navigateTo(); - expect(page.getTitleText()).toEqual('GNS3 Web UI Demo'); + expect(page.getTitleText()).toEqual('GNS3 Web UI'); }); }); diff --git a/electron-builder.yml b/electron-builder.yml index 762ade0f..25db9f3b 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -1,6 +1,6 @@ appId: com.gns3.web-ui copyright: "Copyright © 2018 GNS3" -productName: "GNS3 Web UI Prototype" +productName: "GNS3 Web UI" #forceCodeSigning: true artifactName: "${productName}-${os}-${arch}-${version}.${ext}" asar: true @@ -39,7 +39,7 @@ linux: icon: "dist/assets/icons/png" category: "Network" packageCategory: "Network" - description: "GNS3 Web Ui Prototype application. Please don't use it as long as it's not officially announced." + description: "GNS3 Web UI Prototype application. Please don't use it as long as it's not officially announced." target: - deb - AppImage diff --git a/main.js b/main.js index 9ed733a8..55b72a10 100644 --- a/main.js +++ b/main.js @@ -6,8 +6,6 @@ const path = require('path'); const url = require('url'); const yargs = require('yargs'); -require('./sentry'); - // Keep a global reference of the window object, if you don't, the window will // be closed automatically when the JavaScript object is garbage collected. let mainWindow; @@ -70,7 +68,13 @@ const exitServerProc = () => { function createWindow () { // Create the browser window. - mainWindow = new BrowserWindow({width: 800, height: 600}); + mainWindow = new BrowserWindow({ + width: 800, + height: 600, + webPreferences: { + preload: path.join(__dirname, 'sentry.js') + } + }); // and load the index.html of the app. @@ -83,6 +87,7 @@ function createWindow () { protocol: 'file:', slashes: true })); + mainWindow.maximize(); } if(argv.d) { diff --git a/package.json b/package.json index d805ea67..54d7464a 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "electron-settings": "^3.2.0", "material-design-icons": "^3.0.1", "ngx-electron": "^1.0.4", + "notosans-fontface": "^1.1.0", "npm-check-updates": "^2.14.1", "raven-js": "^3.24.1", "rxjs": "^6.2.1", @@ -61,10 +62,10 @@ "@angular/cli": "^6.0.8", "@angular/compiler-cli": "^6.0.7", "@angular/language-service": "^6.0.7", - "@sentry/electron": "^0.5.5", "@types/jasmine": "~2.8.8", "@types/jasminewd2": "~2.0.2", "@types/node": "~10.5.2", + "@sentry/electron": "^0.7.0", "codelyzer": "~4.4.2", "electron": "2.0.4", "electron-builder": "^20.19.2", @@ -79,7 +80,7 @@ "karma-jasmine-html-reporter": "^1.2.0", "node-sass": "^4.9.1", "popper.js": "^1.14.3", - "protractor": "~5.3.1", + "protractor": "~5.4.0", "ts-mockito": "^2.3.0", "ts-node": "~7.0.0", "tslint": "~5.10.0", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 0813656d..0fb52377 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -82,6 +82,8 @@ import { version } from "./version"; import { ToasterErrorHandler } from "./common/error-handlers/toaster-error-handler"; import { environment } from "../environments/environment"; import { RavenState } from "./common/error-handlers/raven-state-communicator"; +import { ServerDiscoveryComponent } from "./components/servers/server-discovery/server-discovery.component"; +import { ServerDatabase } from './services/server.database'; if (environment.production) { @@ -118,6 +120,7 @@ if (environment.production) { SettingsComponent, LocalServerComponent, ProgressComponent, + ServerDiscoveryComponent, ], imports: [ NgbModule.forRoot(), @@ -174,7 +177,8 @@ if (environment.production) { SelectionManager, InRectangleHelper, DrawingsDataSource, - ServerErrorHandler + ServerErrorHandler, + ServerDatabase ], entryComponents: [ AddServerDialogComponent, diff --git a/src/app/cartography/components/map/map.component.ts b/src/app/cartography/components/map/map.component.ts index e8a269a7..3cfcec9c 100644 --- a/src/app/cartography/components/map/map.component.ts +++ b/src/app/cartography/components/map/map.component.ts @@ -2,7 +2,7 @@ import { Component, ElementRef, HostListener, Input, OnChanges, OnDestroy, OnInit, SimpleChange } from '@angular/core'; import { D3, D3Service } from 'd3-ng2-service'; -import {select, Selection} from 'd3-selection'; +import { select, Selection } from 'd3-selection'; import { Node } from "../../models/node"; import { Link } from "../../../models/link"; @@ -10,7 +10,7 @@ import { GraphLayout } from "../../widgets/graph-layout"; import { Context } from "../../models/context"; import { Size } from "../../models/size"; import { Drawing } from "../../models/drawing"; -import {Symbol} from "../../../models/symbol"; +import { Symbol } from "../../models/symbol"; @Component({ @@ -30,10 +30,9 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy { private d3: D3; private parentNativeElement: any; private svg: Selection; - - public graphLayout: GraphLayout; private graphContext: Context; + public graphLayout: GraphLayout; constructor(protected element: ElementRef, protected d3Service: D3Service @@ -118,12 +117,6 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy { this.graphContext.size = this.getSize(); } - if (this.graphContext != null) { - this.svg - .attr('width', this.graphContext.size.width) - .attr('height', this.graphContext.size.height); - } - this.graphLayout.setNodes(this.nodes); this.graphLayout.setLinks(this.links); this.graphLayout.setDrawings(this.drawings); diff --git a/src/app/cartography/widgets/graph-layout.ts b/src/app/cartography/widgets/graph-layout.ts index eb7d3d9d..d1e2deac 100644 --- a/src/app/cartography/widgets/graph-layout.ts +++ b/src/app/cartography/widgets/graph-layout.ts @@ -82,6 +82,10 @@ export class GraphLayout implements Widget { } draw(view: SVGSelection, context: Context) { + view + .attr('width', context.size.width) + .attr('height', context.size.height); + const canvas = view .selectAll('g.canvas') .data([context]); diff --git a/src/app/components/local-server/local-server.component.spec.ts b/src/app/components/local-server/local-server.component.spec.ts index 58d804d2..bf1a88b4 100644 --- a/src/app/components/local-server/local-server.component.spec.ts +++ b/src/app/components/local-server/local-server.component.spec.ts @@ -34,18 +34,15 @@ describe('LocalServerComponent', () => { }) .compileComponents(); - })); - - beforeEach(() => { fixture = TestBed.createComponent(LocalServerComponent); component = fixture.componentInstance; fixture.detectChanges(); - }); + })); it('should create and redirect to server', fakeAsync(() => { expect(component).toBeTruthy(); expect(serverService.getLocalServer).toHaveBeenCalled(); - // @FIXME: somehow shows it's never called - // expect(router.navigate).toHaveBeenCalledWith('/server', 99, 'projects'); + tick(); + expect(router.navigate).toHaveBeenCalledWith(['/server', 99, 'projects']); })); }); diff --git a/src/app/components/servers/server-discovery/server-discovery.component.html b/src/app/components/servers/server-discovery/server-discovery.component.html new file mode 100644 index 00000000..15d9df49 --- /dev/null +++ b/src/app/components/servers/server-discovery/server-discovery.component.html @@ -0,0 +1,9 @@ + + + We've discovered GNS3 server on {{ discoveredServer.ip }}:{{ discoveredServer.port }}, would you like to add to the list? + + + + + + diff --git a/src/app/components/servers/server-discovery/server-discovery.component.scss b/src/app/components/servers/server-discovery/server-discovery.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/components/servers/server-discovery/server-discovery.component.spec.ts b/src/app/components/servers/server-discovery/server-discovery.component.spec.ts new file mode 100644 index 00000000..2803c0f6 --- /dev/null +++ b/src/app/components/servers/server-discovery/server-discovery.component.spec.ts @@ -0,0 +1,173 @@ +import {async, ComponentFixture, fakeAsync, TestBed, tick} from '@angular/core/testing'; +import { MatCardModule } from "@angular/material"; + +import { Observable } from "rxjs/Rx"; + +import { ServerDiscoveryComponent } from './server-discovery.component'; +import { VersionService } from "../../../services/version.service"; +import { MockedVersionService } from "../../../services/version.service.spec"; +import { Version } from "../../../models/version"; +import { Server } from "../../../models/server"; +import { ServerService } from '../../../services/server.service'; +import { MockedServerService } from '../../../services/server.service.spec'; +import { ServerDatabase } from '../../../services/server.database'; + + +describe('ServerDiscoveryComponent', () => { + let component: ServerDiscoveryComponent; + let fixture: ComponentFixture; + let mockedVersionService: MockedVersionService; + let mockedServerService: MockedServerService; + + beforeEach(async(() => { + mockedServerService = new MockedServerService(); + mockedVersionService = new MockedVersionService(); + TestBed.configureTestingModule({ + imports: [ MatCardModule ], + providers: [ + { provide: VersionService, useFactory: () => mockedVersionService }, + { provide: ServerService, useFactory: () => mockedServerService }, + ServerDatabase + ], + declarations: [ ServerDiscoveryComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ServerDiscoveryComponent); + + component = fixture.componentInstance; + + // we don't really want to run it during testing + spyOn(component, 'ngOnInit').and.returnValue(null); + + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + describe('isAvailable', () => { + it('should return server object when server is available', () => { + const version = new Version(); + version.version = "2.1.8"; + + const getVersionSpy = spyOn(mockedVersionService, 'get') + .and.returnValue(Observable.of(version)); + + component.isServerAvailable('127.0.0.1', 3080).subscribe((s) => { + expect(s.ip).toEqual('127.0.0.1'); + expect(s.port).toEqual(3080); + }); + + const server = new Server(); + server.ip = '127.0.0.1'; + server.port = 3080; + + expect(getVersionSpy).toHaveBeenCalledWith(server); + }); + + it('should throw error once server is not available', () => { + const server = new Server(); + server.ip = '127.0.0.1'; + server.port = 3080; + + const getVersionSpy = spyOn(mockedVersionService, 'get') + .and.returnValue(Observable.throwError(new Error("server is unavailable"))); + let hasExecuted = false; + + component.isServerAvailable('127.0.0.1', 3080).subscribe((ver) => {}, (err) => { + hasExecuted = true; + expect(err.toString()).toEqual('Error: server is unavailable'); + }); + + expect(getVersionSpy).toHaveBeenCalledWith(server); + expect(hasExecuted).toBeTruthy(); + }); + }); + + describe("discovery", () => { + it('should discovery all servers available', (done) => { + const version = new Version(); + version.version = "2.1.8"; + + spyOn(component, 'isServerAvailable').and.callFake((ip, port) => { + const server = new Server(); + server.ip = ip; + server.port = port; + return Observable.of(server); + }); + + component.discovery().subscribe((discovered) => { + expect(discovered[0].ip).toEqual('127.0.0.1'); + expect(discovered[0].port).toEqual(3080); + + expect(discovered.length).toEqual(1); + + done(); + }); + }); + }); + + describe("discoverFirstAvailableServer", () => { + let server: Server; + + beforeEach(function() { + server = new Server(); + server.ip = '199.111.111.1', + server.port = 3333; + + spyOn(component, 'discovery').and.callFake(() => { + return Observable.of([server]); + }); + }); + + it('should get first server from discovered and with no added before', fakeAsync(() => { + expect(component.discoveredServer).toBeUndefined(); + component.discoverFirstAvailableServer(); + tick(); + expect(component.discoveredServer.ip).toEqual('199.111.111.1'); + expect(component.discoveredServer.port).toEqual(3333); + })); + + it('should get first server from discovered and with already added', fakeAsync(() => { + mockedServerService.servers.push(server) + + expect(component.discoveredServer).toBeUndefined(); + component.discoverFirstAvailableServer(); + tick(); + expect(component.discoveredServer).toBeUndefined(); + })); + }); + + describe("accepting and ignoring found server", () => { + let server: Server; + beforeEach(() => { + server = new Server(); + server.ip = '199.111.111.1', + server.port = 3333; + component.discoveredServer = server; + }); + + describe("accept", () => { + it("should add new server", fakeAsync(() => { + component.accept(server); + tick(); + expect(component.discoveredServer).toBeNull(); + expect(mockedServerService.servers[0].ip).toEqual('199.111.111.1'); + expect(mockedServerService.servers[0].name).toEqual('199.111.111.1'); + })); + }); + + describe("ignore", () => { + it("should reject server", fakeAsync(() => { + component.ignore(server); + tick(); + expect(component.discoveredServer).toBeNull(); + })); + }); + }); + +}); diff --git a/src/app/components/servers/server-discovery/server-discovery.component.ts b/src/app/components/servers/server-discovery/server-discovery.component.ts new file mode 100644 index 00000000..fc32ee74 --- /dev/null +++ b/src/app/components/servers/server-discovery/server-discovery.component.ts @@ -0,0 +1,92 @@ +import { Component, OnInit } from '@angular/core'; + +import { Observable } from "rxjs/Rx"; +import { map } from "rxjs//operators"; + +import { Server } from "../../../models/server"; +import { VersionService } from "../../../services/version.service"; +import { Version } from "../../../models/version"; +import { forkJoin } from 'rxjs'; +import { ServerService } from '../../../services/server.service'; +import { ServerDatabase } from '../../../services/server.database'; + + +@Component({ + selector: 'app-server-discovery', + templateUrl: './server-discovery.component.html', + styleUrls: ['./server-discovery.component.scss'] +}) +export class ServerDiscoveryComponent implements OnInit { + private defaultServers = [{ + ip: '127.0.0.1', + port: 3080 + } + ]; + + discoveredServer: Server; + + constructor( + private versionService: VersionService, + private serverService: ServerService, + private serverDatabase: ServerDatabase + ) {} + + ngOnInit() { + this.discoverFirstAvailableServer(); + } + + discoverFirstAvailableServer() { + forkJoin( + Observable.fromPromise(this.serverService.findAll()).pipe(map((s: Server[]) => s)), + this.discovery() + ).subscribe(([local, discovered]) => { + local.forEach((added) => { + discovered = discovered.filter((server) => { + return !(server.ip == added.ip && server.port == added.port); + }); + }); + if(discovered.length > 0) { + this.discoveredServer = discovered.shift(); + } + }); + } + + discovery(): Observable { + const queries: Observable[] = []; + + this.defaultServers.forEach((testServer) => { + queries.push(this.isServerAvailable(testServer.ip, testServer.port).catch((err) => { + return Observable.of(null); + })); + }); + + return new Observable((observer) => { + forkJoin(queries).subscribe((discoveredServers) => { + observer.next(discoveredServers.filter((s) => s != null)); + observer.complete(); + }); + }); + } + + isServerAvailable(ip: string, port: number): Observable { + const server = new Server(); + server.ip = ip; + server.port = port; + return this.versionService.get(server).flatMap((version: Version) => Observable.of(server)); + } + + ignore(server: Server) { + this.discoveredServer = null; + } + + accept(server: Server) { + if(server.name == null) { + server.name = server.ip; + } + + this.serverService.create(server).then((created: Server) => { + this.serverDatabase.addServer(created); + this.discoveredServer = null; + }); + } +} diff --git a/src/app/components/servers/servers.component.html b/src/app/components/servers/servers.component.html index 33bd41fc..b8319d50 100644 --- a/src/app/components/servers/servers.component.html +++ b/src/app/components/servers/servers.component.html @@ -3,6 +3,9 @@

Servers

+ + +
diff --git a/src/app/components/servers/servers.component.ts b/src/app/components/servers/servers.component.ts index 7c8a50d8..5be47f31 100644 --- a/src/app/components/servers/servers.component.ts +++ b/src/app/components/servers/servers.component.ts @@ -1,19 +1,14 @@ -import { Component, Inject, OnInit } from '@angular/core'; +import { Component, Inject, OnInit, Injectable } from '@angular/core'; import { DataSource } from "@angular/cdk/collections"; import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material'; import { Observable, BehaviorSubject, merge } from "rxjs"; import { map } from "rxjs/operators"; -// import 'rxjs/add/operator/startWith'; -// import 'rxjs/add/observable/merge'; -// import 'rxjs/add/operator/map'; -// import 'rxjs/add/operator/debounceTime'; -// import 'rxjs/add/operator/distinctUntilChanged'; -// import 'rxjs/add/observable/fromEvent'; - import { Server } from "../../models/server"; import { ServerService } from "../../services/server.service"; +import { ServerDatabase } from '../../services/server.database'; + @Component({ @@ -22,11 +17,13 @@ import { ServerService } from "../../services/server.service"; styleUrls: ['./servers.component.css'] }) export class ServersComponent implements OnInit { - serverDatabase = new ServerDatabase(); dataSource: ServerDataSource; displayedColumns = ['id', 'name', 'ip', 'port', 'actions']; - constructor(private dialog: MatDialog, private serverService: ServerService) {} + constructor( + private dialog: MatDialog, + private serverService: ServerService, + private serverDatabase: ServerDatabase) {} ngOnInit() { this.serverService.findAll().then((servers: Server[]) => { @@ -89,32 +86,6 @@ export class AddServerDialogComponent implements OnInit { } -export class ServerDatabase { - dataChange: BehaviorSubject = new BehaviorSubject([]); - - get data(): Server[] { - return this.dataChange.value; - } - - public addServer(server: Server) { - const servers = this.data.slice(); - servers.push(server); - this.dataChange.next(servers); - } - - public addServers(servers: Server[]) { - this.dataChange.next(servers); - } - - public remove(server: Server) { - const index = this.data.indexOf(server); - if (index >= 0) { - this.data.splice(index, 1); - this.dataChange.next(this.data.slice()); - } - } -} - export class ServerDataSource extends DataSource { constructor(private serverDatabase: ServerDatabase) { super(); diff --git a/src/app/services/server.database.ts b/src/app/services/server.database.ts new file mode 100644 index 00000000..989a6e50 --- /dev/null +++ b/src/app/services/server.database.ts @@ -0,0 +1,33 @@ +import { Injectable } from "@angular/core"; +import { BehaviorSubject } from "rxjs"; +import { Server } from "../models/server"; + + +@Injectable() +export class ServerDatabase { + dataChange: BehaviorSubject = new BehaviorSubject([]); + + constructor() {} + + get data(): Server[] { + return this.dataChange.value; + } + + public addServer(server: Server) { + const servers = this.data.slice(); + servers.push(server); + this.dataChange.next(servers); + } + + public addServers(servers: Server[]) { + this.dataChange.next(servers); + } + + public remove(server: Server) { + const index = this.data.indexOf(server); + if (index >= 0) { + this.data.splice(index, 1); + this.dataChange.next(this.data.slice()); + } + } +} \ No newline at end of file diff --git a/src/app/services/server.service.spec.ts b/src/app/services/server.service.spec.ts index 3a0204f1..33e8499e 100644 --- a/src/app/services/server.service.spec.ts +++ b/src/app/services/server.service.spec.ts @@ -5,9 +5,20 @@ import { Server } from "../models/server"; import { IndexedDbService } from "./indexed-db.service"; import { AngularIndexedDB } from "angular2-indexeddb"; import Spy = jasmine.Spy; +import { resolve } from 'path'; +import { reject } from 'q'; export class MockedServerService { + public servers: Server[] = []; + + public create(server: Server) { + return new Promise((resolve, reject) => { + this.servers.push(server); + resolve(server); + }); + } + public get(server_id: number) { const server = new Server(); server.id = server_id; @@ -21,6 +32,12 @@ export class MockedServerService { resolve(server); }); } + + public findAll() { + return new Promise((resolve, reject) => { + resolve(this.servers); + }); + } } diff --git a/src/app/services/server.service.ts b/src/app/services/server.service.ts index b8a735ea..e7a377c6 100644 --- a/src/app/services/server.service.ts +++ b/src/app/services/server.service.ts @@ -2,7 +2,6 @@ import { Injectable } from '@angular/core'; import {IndexedDbService} from "./indexed-db.service"; import {Server} from "../models/server"; -import { Observable } from "rxjs"; @Injectable() diff --git a/src/app/services/version.service.spec.ts b/src/app/services/version.service.spec.ts index ef5ca6f4..f70727bc 100644 --- a/src/app/services/version.service.spec.ts +++ b/src/app/services/version.service.spec.ts @@ -7,6 +7,15 @@ import { Server } from '../models/server'; import { getTestServer } from './testing'; import { VersionService } from './version.service'; import { AppTestingModule } from "../testing/app-testing/app-testing.module"; +import {Observable} from "rxjs/Rx"; + +export class MockedVersionService { + public response: Observable; + + public get(server: Server) { + return this.response; + } +} describe('VersionService', () => { diff --git a/src/index.html b/src/index.html index 27657717..72379fa1 100644 --- a/src/index.html +++ b/src/index.html @@ -2,20 +2,21 @@ - GNS3 Web UI Demo + GNS3 Web UI diff --git a/yarn.lock b/yarn.lock index 2551b4c9..5bffba41 100644 --- a/yarn.lock +++ b/yarn.lock @@ -224,47 +224,84 @@ semver "^5.3.0" semver-intersect "^1.1.2" -"@sentry/browser@0.5.4": - version "0.5.4" - resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-0.5.4.tgz#621ff972182b73b62856584b92fc65fde96904cc" +"@sentry/browser@4.0.0-beta.9": + version "4.0.0-beta.9" + resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-4.0.0-beta.9.tgz#1ec41cdac2dfaf509651d9ffc41b25d9c009bce9" dependencies: - "@sentry/core" "0.5.4" - "@sentry/shim" "0.5.4" + "@sentry/core" "4.0.0-beta.9" + "@sentry/hub" "4.0.0-beta.9" + "@sentry/minimal" "4.0.0-beta.9" + "@sentry/types" "4.0.0-beta.9" + "@sentry/utils" "4.0.0-beta.9" -"@sentry/core@0.5.4": - version "0.5.4" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-0.5.4.tgz#9b0a842b442131b3801bae70be2ca4e9c510574e" +"@sentry/core@4.0.0-beta.9": + version "4.0.0-beta.9" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-4.0.0-beta.9.tgz#5b0f4f5693165731136d196cc6e011b555230f20" dependencies: - "@sentry/shim" "0.5.4" + "@sentry/hub" "4.0.0-beta.9" + "@sentry/minimal" "4.0.0-beta.9" + "@sentry/types" "4.0.0-beta.9" + "@sentry/utils" "4.0.0-beta.9" -"@sentry/electron@^0.5.5": - version "0.5.5" - resolved "https://registry.yarnpkg.com/@sentry/electron/-/electron-0.5.5.tgz#9089d6342db6c6bd6c092a53747708031d5fb7c3" +"@sentry/electron@^0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@sentry/electron/-/electron-0.7.0.tgz#ad456c3319c995d84a470304d9890803863587ac" dependencies: - "@sentry/browser" "0.5.4" - "@sentry/core" "0.5.4" - "@sentry/node" "0.5.4" - "@sentry/shim" "0.5.4" - "@sentry/utils" "0.5.4" + "@sentry/browser" "4.0.0-beta.9" + "@sentry/core" "4.0.0-beta.9" + "@sentry/hub" "4.0.0-beta.9" + "@sentry/minimal" "4.0.0-beta.9" + "@sentry/node" "4.0.0-beta.9" + "@sentry/types" "4.0.0-beta.9" + "@sentry/utils" "4.0.0-beta.9" electron-fetch "^1.1.0" form-data "^2.3.2" util.promisify "^1.0.0" -"@sentry/node@0.5.4": - version "0.5.4" - resolved "https://registry.yarnpkg.com/@sentry/node/-/node-0.5.4.tgz#b3e7349d1b361239959036eaae19cebf3564c3d3" +"@sentry/hub@4.0.0-beta.9": + version "4.0.0-beta.9" + resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-4.0.0-beta.9.tgz#a90d666a30d16e6e43b930b49bee46999dbd8a78" dependencies: - "@sentry/core" "0.5.4" - "@sentry/shim" "0.5.4" - raven "^2.6.0" + "@sentry/types" "4.0.0-beta.9" + "@sentry/utils" "4.0.0-beta.9" -"@sentry/shim@0.5.4": - version "0.5.4" - resolved "https://registry.yarnpkg.com/@sentry/shim/-/shim-0.5.4.tgz#cb826b1a34765ae5e1b21e61df2def2f8da91dc1" +"@sentry/minimal@4.0.0-beta.9": + version "4.0.0-beta.9" + resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-4.0.0-beta.9.tgz#d9b95e6586f1be30375c123c4a69b05e18af5669" + dependencies: + "@sentry/hub" "4.0.0-beta.9" + "@sentry/types" "4.0.0-beta.9" -"@sentry/utils@0.5.4": - version "0.5.4" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-0.5.4.tgz#8ede78ace960216dd632fd561c83f50062e5aee1" +"@sentry/node@4.0.0-beta.9": + version "4.0.0-beta.9" + resolved "https://registry.yarnpkg.com/@sentry/node/-/node-4.0.0-beta.9.tgz#4ba35faa585c17c24e6755f6607fde95e8516433" + dependencies: + "@sentry/core" "4.0.0-beta.9" + "@sentry/hub" "4.0.0-beta.9" + "@sentry/minimal" "4.0.0-beta.9" + "@sentry/types" "4.0.0-beta.9" + "@sentry/utils" "4.0.0-beta.9" + "@types/cookie" "0.3.1" + "@types/md5" "2.1.32" + "@types/stack-trace" "0.0.29" + cookie "0.3.1" + lsmod "1.0.0" + md5 "2.2.1" + stack-trace "0.0.10" + +"@sentry/types@4.0.0-beta.9": + version "4.0.0-beta.9" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-4.0.0-beta.9.tgz#1a2f88bfcf62356372a60359b5204e94c079c27d" + +"@sentry/utils@4.0.0-beta.9": + version "4.0.0-beta.9" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-4.0.0-beta.9.tgz#99c61c44280f36b557387d3d37d31240545a7700" + dependencies: + "@sentry/types" "4.0.0-beta.9" + +"@types/cookie@0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.3.1.tgz#720a756ea8e760a258708b52441bd341f1ef4296" "@types/d3-array@*", "@types/d3-array@1.2": version "1.2.1" @@ -439,10 +476,20 @@ dependencies: "@types/jasmine" "*" +"@types/md5@2.1.32": + version "2.1.32" + resolved "https://registry.yarnpkg.com/@types/md5/-/md5-2.1.32.tgz#93e23437fcd17a7b9ca98d02aa6002e835842fe8" + dependencies: + "@types/node" "*" + "@types/mousetrap@^1.6.0": version "1.6.0" resolved "https://registry.yarnpkg.com/@types/mousetrap/-/mousetrap-1.6.0.tgz#c3951ab98b88ff6093cd0b1e4f8591af439141b8" +"@types/node@*", "@types/node@~10.5.2": + version "10.5.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.5.2.tgz#f19f05314d5421fe37e74153254201a7bf00a707" + "@types/node@^6.0.46": version "6.0.114" resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.114.tgz#c42cd56479f32bc1576a5cb19f8a208da9a2b052" @@ -451,17 +498,17 @@ version "8.10.21" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.21.tgz#12b3f2359b27aa05a45d886c8ba1eb8d1a77e285" -"@types/node@~10.5.2": - version "10.5.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.5.2.tgz#f19f05314d5421fe37e74153254201a7bf00a707" - "@types/q@^0.0.32": version "0.0.32" resolved "https://registry.yarnpkg.com/@types/q/-/q-0.0.32.tgz#bd284e57c84f1325da702babfc82a5328190c0c5" -"@types/selenium-webdriver@^2.53.35", "@types/selenium-webdriver@~2.53.39": - version "2.53.43" - resolved "https://registry.yarnpkg.com/@types/selenium-webdriver/-/selenium-webdriver-2.53.43.tgz#2de3d718819bc20165754c4a59afb7e9833f6707" +"@types/selenium-webdriver@^3.0.0": + version "3.0.10" + resolved "https://registry.yarnpkg.com/@types/selenium-webdriver/-/selenium-webdriver-3.0.10.tgz#e98cc6f05b4b436277671c784ee2f9d05a634f9b" + +"@types/stack-trace@0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/stack-trace/-/stack-trace-0.0.29.tgz#eb7a7c60098edb35630ed900742a5ecb20cfcb4d" "@webassemblyjs/ast@1.4.3": version "1.4.3" @@ -619,10 +666,6 @@ addressparser@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/addressparser/-/addressparser-1.0.1.tgz#47afbe1a2a9262191db6838e4fd1d39b40821746" -adm-zip@0.4.4: - version "0.4.4" - resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.4.tgz#a61ed5ae6905c3aea58b3a657d25033091052736" - adm-zip@^0.4.9: version "0.4.11" resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.11.tgz#2aa54c84c4b01a9d0fb89bb11982a51f13e3d62a" @@ -1317,6 +1360,12 @@ browserslist@^3.2.8: caniuse-lite "^1.0.30000844" electron-to-chromium "^1.3.47" +browserstack@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/browserstack/-/browserstack-1.5.1.tgz#e2dfa66ffee940ebad0a07f7e00fd4687c455d66" + dependencies: + https-proxy-agent "^2.2.1" + buffer-from@^1.0.0, buffer-from@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.0.tgz#87fcaa3a298358e0ade6e442cfce840740d1ad04" @@ -5046,6 +5095,10 @@ lru-cache@^4.0.1, lru-cache@^4.1.1, lru-cache@^4.1.2: pseudomap "^1.0.2" yallist "^2.1.2" +lsmod@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lsmod/-/lsmod-1.0.0.tgz#9a00f76dca36eb23fa05350afe1b585d4299e64b" + mailcomposer@4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/mailcomposer/-/mailcomposer-4.0.1.tgz#0e1c44b2a07cf740ee17dc149ba009f19cadfeb4" @@ -5106,7 +5159,7 @@ md5.js@^1.3.4: hash-base "^3.0.0" inherits "^2.0.1" -md5@^2.2.1: +md5@2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9" dependencies: @@ -5613,6 +5666,10 @@ normalize-range@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" +notosans-fontface@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/notosans-fontface/-/notosans-fontface-1.1.0.tgz#327fd8b54aa3249a44678605d912e31f1449b855" + npm-bundled@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.3.tgz#7e71703d973af3370a9591bafe3a63aca0be2308" @@ -5977,10 +6034,6 @@ optionator@^0.8.1: type-check "~0.3.2" wordwrap "~1.0.0" -options@>=0.0.5: - version "0.0.6" - resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f" - original@>=0.0.5: version "1.0.1" resolved "https://registry.yarnpkg.com/original/-/original-1.0.1.tgz#b0a53ff42ba997a8c9cd1fb5daaeb42b9d693190" @@ -6445,14 +6498,15 @@ proto-list@~1.2.1: version "1.2.4" resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" -protractor@~5.3.1: - version "5.3.2" - resolved "https://registry.yarnpkg.com/protractor/-/protractor-5.3.2.tgz#b8278f3131d9d52fa1172ed0f7fec03085fbe0ce" +protractor@~5.4.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/protractor/-/protractor-5.4.0.tgz#e71c9c1f5cf6c5e9bdbcdb71e7f31b17ffd2878f" dependencies: "@types/node" "^6.0.46" "@types/q" "^0.0.32" - "@types/selenium-webdriver" "~2.53.39" + "@types/selenium-webdriver" "^3.0.0" blocking-proxy "^1.0.0" + browserstack "^1.5.1" chalk "^1.1.3" glob "^7.0.3" jasmine "2.8.0" @@ -6462,7 +6516,7 @@ protractor@~5.3.1: saucelabs "^1.5.0" selenium-webdriver "3.6.0" source-map-support "~0.4.0" - webdriver-js-extender "^1.0.0" + webdriver-js-extender "2.0.0" webdriver-manager "^12.0.6" proxy-addr@~2.0.3: @@ -6603,16 +6657,6 @@ raven-js@^3.24.1: version "3.26.3" resolved "https://registry.yarnpkg.com/raven-js/-/raven-js-3.26.3.tgz#0efb49969b5b11ab965f7b0d6da4ca102b763cb0" -raven@^2.6.0: - version "2.6.3" - resolved "https://registry.yarnpkg.com/raven/-/raven-2.6.3.tgz#207475a12809277ef54eaceafe2597ff65262ab4" - dependencies: - cookie "0.3.1" - md5 "^2.2.1" - stack-trace "0.0.10" - timed-out "4.0.1" - uuid "3.0.0" - raw-body@2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89" @@ -7167,10 +7211,6 @@ sax@0.5.x: version "0.5.8" resolved "https://registry.yarnpkg.com/sax/-/sax-0.5.8.tgz#d472db228eb331c2506b0e8c15524adb939d12c1" -sax@0.6.x: - version "0.6.1" - resolved "https://registry.yarnpkg.com/sax/-/sax-0.6.1.tgz#563b19c7c1de892e09bfc4f2fc30e3c27f0952b9" - sax@>=0.6.0, sax@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" @@ -7199,7 +7239,7 @@ select-hose@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" -selenium-webdriver@3.6.0: +selenium-webdriver@3.6.0, selenium-webdriver@^3.0.1: version "3.6.0" resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz#2ba87a1662c020b8988c981ae62cb2a01298eafc" dependencies: @@ -7208,16 +7248,6 @@ selenium-webdriver@3.6.0: tmp "0.0.30" xml2js "^0.4.17" -selenium-webdriver@^2.53.2: - version "2.53.3" - resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-2.53.3.tgz#d29ff5a957dff1a1b49dc457756e4e4bfbdce085" - dependencies: - adm-zip "0.4.4" - rimraf "^2.2.8" - tmp "0.0.24" - ws "^1.0.1" - xml2js "0.4.4" - selfsigned@^1.9.1: version "1.10.3" resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.3.tgz#d628ecf9e3735f84e8bafba936b3cf85bea43823" @@ -7967,7 +7997,7 @@ thunky@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.0.2.tgz#a862e018e3fb1ea2ec3fce5d55605cf57f247371" -timed-out@4.0.1, timed-out@^4.0.0: +timed-out@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" @@ -7981,10 +8011,6 @@ timespan@2.3.x: version "2.3.0" resolved "https://registry.yarnpkg.com/timespan/-/timespan-2.3.0.tgz#4902ce040bd13d845c8f59b27e9d59bad6f39929" -tmp@0.0.24: - version "0.0.24" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.24.tgz#d6a5e198d14a9835cc6f2d7c3d9e302428c8cf12" - tmp@0.0.30: version "0.0.30" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.30.tgz#72419d4a8be7d6ce75148fd8b324e593a711c2ed" @@ -8215,10 +8241,6 @@ uid-number@0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" -ultron@1.0.x: - version "1.0.2" - resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa" - ultron@~1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" @@ -8404,10 +8426,6 @@ utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" -uuid@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.0.tgz#6728fc0459c450d796a99c31837569bdf672d728" - uuid@^3.0.0, uuid@^3.0.1, uuid@^3.1.0: version "3.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" @@ -8487,12 +8505,12 @@ webassemblyjs@1.4.3: "@webassemblyjs/wast-parser" "1.4.3" long "^3.2.0" -webdriver-js-extender@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/webdriver-js-extender/-/webdriver-js-extender-1.0.0.tgz#81c533a9e33d5bfb597b4e63e2cdb25b54777515" +webdriver-js-extender@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/webdriver-js-extender/-/webdriver-js-extender-2.0.0.tgz#b27fc1ed1afbf78f0ac57e4c878f31b10e57f146" dependencies: - "@types/selenium-webdriver" "^2.53.35" - selenium-webdriver "^2.53.2" + "@types/selenium-webdriver" "^3.0.0" + selenium-webdriver "^3.0.1" webdriver-manager@^12.0.6: version "12.1.0" @@ -8721,13 +8739,6 @@ write-file-atomic@~1.2.0: imurmurhash "^0.1.4" slide "^1.1.5" -ws@^1.0.1: - version "1.1.5" - resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.5.tgz#cbd9e6e75e09fc5d2c90015f21f0c40875e0dd51" - dependencies: - options ">=0.0.5" - ultron "1.0.x" - ws@~3.3.1: version "3.3.3" resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" @@ -8740,13 +8751,6 @@ xdg-basedir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" -xml2js@0.4.4: - version "0.4.4" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.4.tgz#3111010003008ae19240eba17497b57c729c555d" - dependencies: - sax "0.6.x" - xmlbuilder ">=1.0.0" - xml2js@^0.4.17: version "0.4.19" resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" @@ -8758,10 +8762,6 @@ xmlbuilder@8.2.2: version "8.2.2" resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-8.2.2.tgz#69248673410b4ba42e1a6136551d2922335aa773" -xmlbuilder@>=1.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-10.0.0.tgz#c64e52f8ae097fe5fd46d1c38adaade071ee1b55" - xmlbuilder@^9.0.7, xmlbuilder@~9.0.1: version "9.0.7" resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d"