Update code formatting

This commit is contained in:
Thomas Nordquist
2019-06-15 14:56:57 +02:00
parent 6176859c7c
commit 92e045297e
115 changed files with 2988 additions and 1042 deletions

View File

@@ -1,11 +1,12 @@
export interface Scene {
name: SceneNames,
name: SceneNames
start: number
stop: number
duration: number
}
export type SceneNames = 'connect'
export type SceneNames =
| 'connect'
| 'topic_updates'
| 'numeric_plots'
| 'json-formatting'

View File

@@ -1,30 +1,23 @@
import * as fs from 'fs'
import * as os from 'os'
import * as webdriverio from 'webdriverio'
import mockMqtt, { stop as stopMqtt } from './mock-mqtt'
import { clearOldTopics } from './scenarios/clearOldTopics'
import { clearSearch, searchTree } from './scenarios/searchTree'
import { clickOnHistory, createFakeMousePointer, hideText, showText, sleep } from './util'
import { connectTo } from './scenarios/connect'
import { copyTopicToClipboard } from './scenarios/copyTopicToClipboard'
import { copyValueToClipboard } from './scenarios/copyValueToClipboard'
import { disconnect } from './scenarios/disconnect'
import { publishTopic } from './scenarios/publishTopic'
import { SceneBuilder } from './SceneBuilder'
import { showAdvancedConnectionSettings } from './scenarios/showAdvancedConnectionSettings'
import { showJsonFormatting } from './scenarios/showJsonFormatting'
import { showJsonPreview } from './scenarios/showJsonPreview'
import { showMenu } from './scenarios/showMenu'
import { showNumericPlot } from './scenarios/showNumericPlot'
import { showOffDiffCapability } from './scenarios/showOffDiffCapability'
import { showZoomLevel } from './scenarios/showZoomLevel'
import { showAdvancedConnectionSettings } from './scenarios/showAdvancedConnectionSettings'
import { SceneBuilder } from './SceneBuilder'
import * as fs from 'fs'
import {
clickOnHistory,
createFakeMousePointer,
hideText,
showText,
sleep,
} from './util'
process.on('unhandledRejection', (error: Error | any) => {
console.error('unhandledRejection', error.message, error.stack)
@@ -41,7 +34,13 @@ const options = {
browserName: 'electron',
chromeOptions: {
binary: `${__dirname}/../../../node_modules/.bin/electron`,
args: [`--app=${__dirname}/../../..`, '--force-device-scale-factor=1', '--no-sandbox', '--disable-dev-shm-usage', '--disable-extensions'].concat(runningUiTestOnCi),
args: [
`--app=${__dirname}/../../..`,
'--force-device-scale-factor=1',
'--no-sandbox',
'--disable-dev-shm-usage',
'--disable-extensions',
].concat(runningUiTestOnCi),
},
windowTypes: ['app', 'webview'],
},
@@ -55,7 +54,6 @@ async function doStuff() {
const browser = await webdriverio.remote(options)
await createFakeMousePointer(browser)
// Wait for Username input to be visible
await browser.$('//label[contains(text(), "Username")]/..//input')
const scenes = new SceneBuilder()

View File

@@ -1,15 +1,6 @@
import * as fs from 'fs'
import * as os from 'os'
import * as webdriverio from 'webdriverio'
import mockMqtt, { stopUpdates as stopMqttUpdates } from './mock-mqtt'
import {
ClassNameMapping,
countInstancesOf,
createFakeMousePointer,
getHeapDump,
setFast,
sleep
} from './util'
import { ClassNameMapping, countInstancesOf, createFakeMousePointer, getHeapDump, setFast, sleep } from './util'
import { clearSearch, searchTree } from './scenarios/searchTree'
import { connectTo } from './scenarios/connect'
import { reconnect } from './scenarios/reconnect'
@@ -29,7 +20,13 @@ const options = {
browserName: 'electron',
chromeOptions: {
binary: `${__dirname}/../../../node_modules/.bin/electron`,
args: [`--app=${__dirname}/../../..`, '--force-device-scale-factor=1', '--no-sandbox', '--disable-dev-shm-usage', '--disable-extensions'].concat(runningUiTestOnCi),
args: [
`--app=${__dirname}/../../..`,
'--force-device-scale-factor=1',
'--no-sandbox',
'--disable-dev-shm-usage',
'--disable-extensions',
].concat(runningUiTestOnCi),
},
windowTypes: ['app', 'webview'],
},
@@ -40,7 +37,7 @@ async function doStuff() {
await mockMqtt()
console.log('start webdriver')
const browser = await webdriverio.remote(options)
const browser = await WebdriverIO.remote(options)
setFast()
await createFakeMousePointer(browser)
@@ -50,10 +47,10 @@ async function doStuff() {
stopMqttUpdates()
await sleep(1000, true)
let heapDump = await getHeapDump(browser)
const initialTreeOccurrances = await countInstancesOf(heapDump, ClassNameMapping.Tree)
const initialNodeOccurrances = await countInstancesOf(heapDump, ClassNameMapping.TreeNode)
console.log(initialTreeOccurrances, initialNodeOccurrances)
const heapDump = await getHeapDump(browser)
const initialTreeOccurrences = await countInstancesOf(heapDump, ClassNameMapping.Tree)
const initialNodeOccurrences = await countInstancesOf(heapDump, ClassNameMapping.TreeNode)
console.log(initialTreeOccurrences, initialNodeOccurrences)
await doX(3, async () => {
await reconnect(browser)
@@ -74,36 +71,49 @@ async function doStuff() {
await sleep(1000, true)
await waitForGarbageCollectorToDetermineLeak(browser, initialTreeOccurrances, initialNodeOccurrances)
await waitForGarbageCollectorToDetermineLeak(browser, initialTreeOccurrences, initialNodeOccurrences)
}
async function waitForGarbageCollectorToDetermineLeak(browser: any, initialTreeOccurrances: number, initialNodeOccurrances: number) {
async function waitForGarbageCollectorToDetermineLeak(
browser: any,
initialTreeOccurrences: number,
initialNodeOccurrences: number
) {
let delta = -1
let lastTreeOccurances = -1
let lastNodeOccurances = -1
let lastTreeOccurrences = -1
let lastNodeOccurrences = -1
let leak = false
while (delta < 0) {
if (lastTreeOccurances !== -1) {
if (lastTreeOccurrences !== -1) {
await sleep(10000, true)
}
const heapDump = await getHeapDump(browser)
const currentTreeOccurrances = await countInstancesOf(heapDump, ClassNameMapping.Tree)
const currentNodeOccurrances = await countInstancesOf(heapDump, ClassNameMapping.TreeNode)
const currentTreeOccurrences = await countInstancesOf(heapDump, ClassNameMapping.Tree)
const currentNodeOccurrences = await countInstancesOf(heapDump, ClassNameMapping.TreeNode)
// Temporary "leaks" are expected due to React Fibers memoization
if (Math.abs(initialTreeOccurrances - currentTreeOccurrances) > 1 || Math.abs(currentNodeOccurrances - initialNodeOccurrances) > 8) {
console.error('Possible leak detected', initialTreeOccurrances, currentTreeOccurrances, initialNodeOccurrances, currentNodeOccurrances)
if (
Math.abs(initialTreeOccurrences - currentTreeOccurrences) > 1 ||
Math.abs(currentNodeOccurrences - initialNodeOccurrences) > 8
) {
console.error(
'Possible leak detected',
initialTreeOccurrences,
currentTreeOccurrences,
initialNodeOccurrences,
currentNodeOccurrences
)
leak = true
} else {
leak = false
}
const treeDelta = lastTreeOccurances >= 0 ? currentTreeOccurrances - lastTreeOccurances : -1
const nodeDelta = lastTreeOccurances >= 0 ? currentNodeOccurrances - lastNodeOccurances : -1
const treeDelta = lastTreeOccurrences >= 0 ? currentTreeOccurrences - lastTreeOccurrences : -1
const nodeDelta = lastTreeOccurrences >= 0 ? currentNodeOccurrences - lastNodeOccurrences : -1
delta = treeDelta + nodeDelta
lastTreeOccurances = currentTreeOccurrances
lastNodeOccurances = currentNodeOccurrances
lastTreeOccurrences = currentTreeOccurrences
lastNodeOccurrences = currentNodeOccurrences
}
if (leak) {

View File

@@ -1,23 +1,20 @@
import * as mqtt from 'mqtt'
const settings = {
port: 1883,
}
let client: mqtt.MqttClient
let mqttClient: mqtt.MqttClient
function startServer(): Promise<mqtt.MqttClient> {
return new Promise(async (resolve) => {
// const server = new mosca.Server(settings)
// await new Promise(resolve => server.once('ready', resolve))
client = await connectMqtt()
generateData(client)
resolve(client)
return new Promise(async resolve => {
mqttClient = await connectMqtt()
generateData(mqttClient)
resolve(mqttClient)
})
}
function connectMqtt(): Promise<mqtt.MqttClient> {
return new Promise((resolve) => {
const client = mqtt.connect('mqtt://127.0.0.1:1883', { username: 'thomas', password: 'bierbier' })
return new Promise(resolve => {
const client = mqtt.connect('mqtt://127.0.0.1:1883', {
username: 'thomas',
password: 'bierbier',
})
client.once('connect', () => {
resolve(client)
})
@@ -40,8 +37,10 @@ export function stopUpdates() {
export function stop() {
stopUpdates()
try {
client && client.end()
} catch {}
mqttClient && mqttClient.end()
} catch {
// ignore
}
}
let intervals: any = []
@@ -49,20 +48,36 @@ let intervals: any = []
function generateData(client: mqtt.MqttClient) {
client.publish('livingroom/lamp/state', 'on', { retain: true, qos: 0 })
client.publish('livingroom/lamp/brightness', '128', { retain: true, qos: 0 })
client.publish('livingroom/thermostat/targetTemperature', '20°C', { retain: true, qos: 0 })
client.publish('livingroom/thermostat/targetTemperature', '20°C', {
retain: true,
qos: 0,
})
intervals.push(setInterval(() => client.publish('livingroom/temperature', temperature()), 1000))
intervals.push(setInterval(() => client.publish('livingroom/humidity', temperature(60, -2, 0)), 1000))
client.publish('livingroom/lamp-1/state', 'on', { retain: true, qos: 0 })
client.publish('livingroom/lamp-1/brightness', '48', { retain: true, qos: 0 })
client.publish('livingroom/lamp-1/brightness', '48', {
retain: true,
qos: 0,
})
client.publish('livingroom/lamp-2/state', 'off', { retain: true, qos: 0 })
client.publish('livingroom/lamp-2/brightness', '48', { retain: true, qos: 0 })
client.publish('livingroom/lamp-2/brightness', '48', {
retain: true,
qos: 0,
})
client.publish('kitchen/lamp/state', 'off', { retain: true, qos: 0 })
client.subscribe('kitchen/lamp/set')
client.on('message', (topic, payload) => {
if (topic === 'kitchen/lamp/set') {
setTimeout(() => client.publish('kitchen/lamp/state', payload, { retain: true, qos: 0 }), 500)
setTimeout(
() =>
client.publish('kitchen/lamp/state', payload, {
retain: true,
qos: 0,
}),
500
)
}
})
@@ -74,7 +89,10 @@ function generateData(client: mqtt.MqttClient) {
client.publish('garden/lamps/state', 'off', { retain: true, qos: 0 })
client.publish('garden/lamps/state', 'off', { retain: true, qos: 0 })
client.publish('zigbee2mqtt/bridge/state', 'online', { retain: true, qos: 0 })
client.publish('zigbee2mqtt/bridge/state', 'online', {
retain: true,
qos: 0,
})
client.publish('ble2mqtt/bridge/state', 'online', { retain: true, qos: 0 })
// Used for demonstrating "clean up"
@@ -84,30 +102,33 @@ function generateData(client: mqtt.MqttClient) {
// Just stuff
client.publish('01-80-C2-00-00-0F/LWT', 'offline', { retain: true, qos: 0 })
intervals.push(setInterval(() => {
client.publish('3d-printer/OctoPrint/temperature/bed', '{"_timestamp":1548589083,"actual":25.9,"target":0}')
client.publish('3d-printer/OctoPrint/temperature/tool0', '{"_timestamp":1548589093,"actual":26.4,"target":0}')
}, 3333))
intervals.push(
setInterval(() => {
client.publish('3d-printer/OctoPrint/temperature/bed', '{"_timestamp":1548589083,"actual":25.9,"target":0}')
client.publish('3d-printer/OctoPrint/temperature/tool0', '{"_timestamp":1548589093,"actual":26.4,"target":0}')
}, 3333)
)
let state = true
intervals.push(setInterval(() => {
state = !state
const js = {
tags: {
entityId: 33512,
entityType: 'person',
host: 'd44ad81e10f9',
server: 'http://localhost/dataActuality',
status: state ? 'live' : 'inactive',
},
timestamp: Date.now(),
}
client.publish(
'actuality/showcase',
JSON.stringify(js),
{ retain: true, qos: 0 }
)
}, 2102))
intervals.push(
setInterval(() => {
state = !state
const js = {
tags: {
entityId: 33512,
entityType: 'person',
host: 'd44ad81e10f9',
server: 'http://localhost/dataActuality',
status: state ? 'live' : 'inactive',
},
timestamp: Date.now(),
}
client.publish('actuality/showcase', JSON.stringify(js), {
retain: true,
qos: 0,
})
}, 2102)
)
}
export default startServer

View File

@@ -1,5 +1,5 @@
import { clickOn, sleep, writeText, expandTopic, moveToCenterOfElement } from '../util'
import { Browser } from 'webdriverio'
import { Browser, Element } from 'webdriverio'
import { clickOn, expandTopic, moveToCenterOfElement, sleep, writeText } from '../util'
export async function clearOldTopics(browser: Browser) {
const topics = ['hello', 'test 123']

View File

@@ -1,5 +1,5 @@
import { Browser, Element } from 'webdriverio'
import { clickOn, writeTextToInput } from '../util'
import { Browser } from 'webdriverio'
export async function connectTo(host: string, browser: Browser) {
await writeTextToInput('Host', host, browser)

View File

@@ -1,5 +1,5 @@
import { Browser, Element } from 'webdriverio'
import { clickOn } from '../util'
import { Browser } from 'webdriverio'
export async function copyTopicToClipboard(browser: Browser) {
const copyButton = await browser.$('//p[contains(text(), "Topic")]/span')

View File

@@ -1,5 +1,5 @@
import { clickOn, sleep, writeText, expandTopic } from '../util'
import { Browser } from 'webdriverio'
import { Browser, Element } from 'webdriverio'
import { clickOn, expandTopic, sleep, writeText } from '../util'
export async function copyValueToClipboard(browser: Browser) {
const copyButton = await browser.$('//p[contains(text(), "Value")]/span')

View File

@@ -1,5 +1,5 @@
import { Browser, Element } from 'webdriverio'
import { clickOn } from '../util'
import { Browser } from 'webdriverio'
export async function disconnect(browser: Browser) {
const disconnectButton = await browser.$('//button/span[contains(text(),"Disconnect")]')

View File

@@ -1,5 +1,13 @@
import { clickOn, sleep, writeText, delteTextWithBackspaces, expandTopic, moveToCenterOfElement, showText } from '../util'
import { Browser } from 'webdriverio'
import { Browser, Element } from 'webdriverio'
import {
clickOn,
sleep,
writeText,
delteTextWithBackspaces,
expandTopic,
moveToCenterOfElement,
showText,
} from '../util'
export async function publishTopic(browser: Browser) {
await expandTopic('kitchen/lamp/state', browser)

View File

@@ -1,5 +1,5 @@
import { Browser, Element } from 'webdriverio'
import { clickOn } from '../util'
import { Browser } from 'webdriverio'
export async function reconnect(browser: Browser) {
const disconnectButton = await browser.$('//button/span[contains(text(),"Disconnect")]')

View File

@@ -1,5 +1,5 @@
import { clickOn, sleep, writeText, delteTextWithBackspaces, showText } from '../util'
import { Browser } from 'webdriverio'
import { Browser, Element } from 'webdriverio'
import { clickOn, delteTextWithBackspaces, showText, sleep, writeText } from '../util'
export async function searchTree(text: string, browser: Browser) {
const searchField = await browser.$('//input[contains(@placeholder, "Search")]')

View File

@@ -1,5 +1,5 @@
import { clickOn, writeTextToInput, sleep } from '../util'
import { Browser } from 'webdriverio'
import { Browser, Element } from 'webdriverio'
import { clickOn, sleep, writeTextToInput } from '../util'
export async function showAdvancedConnectionSettings(browser: Browser) {
const advancedSettingsButton = await browser.$('//button/span[contains(text(),"Advanced")]')

View File

@@ -1,8 +1,5 @@
import { Browser } from 'webdriverio'
import {
clickOn,
sleep
} from '../util'
import { Browser, Element } from 'webdriverio'
import { clickOn, sleep } from '../util'
export async function showJsonFormatting(browser: Browser) {
const editor = await browser.$('//*[contains(@class, "ace_editor")]')

View File

@@ -1,4 +1,4 @@
import { Browser } from 'webdriverio'
import { Browser, Element } from 'webdriverio'
import { expandTopic, sleep } from '../util'
export async function showJsonPreview(browser: Browser) {

View File

@@ -1,5 +1,5 @@
import { clickOn, sleep, writeText, expandTopic, moveToCenterOfElement, showText } from '../util'
import { Browser } from 'webdriverio'
import { Browser, Element } from 'webdriverio'
import { clickOn, expandTopic, moveToCenterOfElement, showText, sleep, writeText } from '../util'
export async function showMenu(browser: Browser) {
const menuButton = await browser.$('//button[contains(@aria-label, "Menu")]')

View File

@@ -1,5 +1,5 @@
import { clickOn, sleep, writeText, expandTopic, clickOnHistory } from '../util'
import { Browser } from 'webdriverio'
import { Browser, Element } from 'webdriverio'
import { clickOn, clickOnHistory, expandTopic, sleep, writeText } from '../util'
export async function showNumericPlot(browser: Browser) {
await expandTopic('livingroom/temperature', browser)

View File

@@ -1,5 +1,5 @@
import { clickOn, sleep, showText } from '../util'
import { Browser } from 'webdriverio'
import { Browser, Element } from 'webdriverio'
import { clickOn, showText, sleep } from '../util'
// Expects a topic with at least two messages to be selected
export async function showOffDiffCapability(browser: Browser) {

View File

@@ -1,5 +1,5 @@
import { sleep, showKeys, showText } from '../util'
import { Browser } from 'webdriverio'
import { Browser, Element } from 'webdriverio'
import { showKeys, showText, sleep } from '../util'
export async function showZoomLevel(browser: Browser) {
await showKeys('Zoom in', 2000, browser, 'top', ['Ctrl', '+'])

View File

@@ -1,10 +1,10 @@
import { Browser } from 'webdriverio'
import { clickOn } from './'
import { Browser, Element } from 'webdriverio'
export async function expandTopic(path: string, browser: Browser) {
const originalTopics = path.split('/')
let topics = path.split('/')
while (topics.length > 0 && !await topicMatches(topics, browser)) {
while (topics.length > 0 && !(await topicMatches(topics, browser))) {
topics = topics.slice(0, topics.length - 1)
}
if (topics.length === 0) {
@@ -18,12 +18,12 @@ export async function expandTopic(path: string, browser: Browser) {
}
}
async function topicMatches(topics: string[], browser: Browser) {
async function topicMatches(topics: Array<string>, browser: Browser) {
const result = await browser.$(topicSelector(topics))
return result.isExisting()
}
function topicSelector(topics: string[]) {
function topicSelector(topics: Array<string>) {
const suffix = topics.map(topic => `*[contains(text(), "${topic}")]`).join('/../..//')
return `//${suffix}`
}

View File

@@ -1,5 +1,6 @@
import * as fs from 'fs'
import { Browser, Element } from 'webdriverio'
export { expandTopic } from './expandTopic'
let fast = false
@@ -8,7 +9,7 @@ export function setFast() {
}
export function sleep(ms: number, required = false) {
return new Promise((resolve) => {
return new Promise(resolve => {
if (required) {
setTimeout(resolve, ms)
} else {
@@ -39,9 +40,9 @@ export async function delteTextWithBackspaces(element: Element, browser: Browser
export async function writeTextToInput(name: string, text: string, browser: Browser, wait: boolean = true) {
const input = await browser.$(`//label[contains(text(), "${name}")]/..//input`)
await clickOn(input, browser, 1)
wait && await sleep(500)
wait && (await sleep(500))
input.clearValue()
wait && await sleep(300)
wait && (await sleep(300))
await writeText(text, browser)
}
@@ -81,7 +82,13 @@ export async function createFakeMousePointer(browser: Browser) {
await browser.execute(js)
}
export async function showText(text: string, duration: number = 0, browser: Browser, location: 'top' | 'bottom' | 'middle' = 'bottom', keys = []) {
export async function showText(
text: string,
duration: number = 0,
browser: Browser,
location: 'top' | 'bottom' | 'middle' = 'bottom',
keys = []
) {
const js = `window.demo.showMessage('${text}', '${location}', ${duration});`
await browser.execute(js)
@@ -106,12 +113,16 @@ export enum ClassNameMapping {
}
export async function countInstancesOf(heapDump: HeapDump, className: ClassNameMapping): Promise<number> {
return heapDump.nodes
.map((idx: number) => heapDump.strings[idx])
.filter((s: string) => s === className).length
return heapDump.nodes.map((idx: number) => heapDump.strings[idx]).filter((s: string) => s === className).length
}
export async function showKeys(text: string, duration: number = 0, browser: Browser, location: 'top' | 'bottom' | 'middle' = 'bottom', keys: string[] = []) {
export async function showKeys(
text: string,
duration: number = 0,
browser: Browser,
location: 'top' | 'bottom' | 'middle' = 'bottom',
keys: Array<string> = []
) {
const js = `window.demo.showMessage('${text}', '${location}', ${duration}, ${JSON.stringify(keys)});`
await browser.execute(js)