cypress testing

pull/471/head
hunterlong 2020-03-31 03:13:02 -07:00
parent 74f584b591
commit e6a4dd3e45
13 changed files with 286 additions and 70 deletions

View File

@ -10,8 +10,8 @@
},
"baseUrl": "http://localhost:8888",
"chromeWebSecurity": false,
"defaultCommandTimeout": 5000,
"requestTimeout": 5000,
"defaultCommandTimeout": 8000,
"requestTimeout": 8000,
"watchForFileChanges": false,
"failOnStatusCode": false
}

View File

@ -40,8 +40,8 @@ context('Setup Process', () => {
cy.get('#password_confirm').clear().type('admin')
cy.get('button[type="submit"]').click()
cy.get('.pt-4').should('contain', 'Demo Tester')
cy.get('.mb-5').should('contain', 'This is a test from Crypress!')
cy.get('#title').should('contain', 'Demo Tester')
cy.get('#description').should('contain', 'This is a test from Crypress!')
cy.get('.list-group').should('have.length', 5)
cy.get('.card').should('have.length', 5)
})

View File

@ -0,0 +1,61 @@
/// <reference types="cypress" />
import "../support/commands"
context('Groups Tests', () => {
beforeEach(() => {
cy.restoreLocalStorageCache();
});
afterEach(() => {
cy.saveLocalStorageCache();
});
it('should Login', () => {
cy.visit('/login')
cy.get('#username').clear().type('admin')
cy.get('#password').clear().type('admin')
cy.get('button[type="submit"]').click()
cy.get('.navbar-brand').should('contain', 'Statping')
cy.getCookies()
cy.getCookies().should('have.length', 1)
})
it('should goto groups', () => {
cy.visit('/dashboard/services')
cy.get('.sortable_groups > tr').should('have.length', 3)
cy.get('.sortable_groups > tr').eq(0).contains('PRIVATE')
cy.get('.sortable_groups > tr').eq(1).contains('PUBLIC')
cy.get('.sortable_groups > tr').eq(2).contains('PRIVATE')
})
it('should create new Group', () => {
cy.visit('/dashboard/services')
cy.get('#title').clear().type('Test Group')
cy.get('button[type="submit"]').click()
})
it('should create new Private Group', () => {
cy.visit('/dashboard/services')
cy.get('#title').clear().type('Test Private Group')
cy.get('.float-left > label').click()
cy.get('button[type="submit"]').click()
})
it('should confirm new groups', () => {
cy.visit('/dashboard/services')
cy.get('.sortable_groups > tr').should('have.length', 5)
cy.get('.sortable_groups > tr').eq(0).contains('PRIVATE')
cy.get('.sortable_groups > tr').eq(0).contains('Test Private Group')
cy.get('.sortable_groups > tr').eq(1).contains('PUBLIC')
cy.get('.sortable_groups > tr').eq(1).contains('Test Group')
})
})

View File

@ -0,0 +1,46 @@
/// <reference types="cypress" />
import "../support/commands"
context('Messages Tests', () => {
beforeEach(() => {
cy.restoreLocalStorageCache();
});
afterEach(() => {
cy.saveLocalStorageCache();
});
it('should Login', () => {
cy.visit('/login')
cy.get('#username').clear().type('admin')
cy.get('#password').clear().type('admin')
cy.get('button[type="submit"]').click()
cy.get('.navbar-brand').should('contain', 'Statping')
cy.getCookies()
cy.getCookies().should('have.length', 1)
})
it('should goto messages', () => {
cy.visit('/dashboard/messages')
cy.get('tbody > tr').should('have.length', 2)
})
it('should create Message', () => {
cy.visit('/dashboard/messages')
cy.get('#title').clear().type('Test Message')
cy.get('#description').clear().type('This message was created by Cypress!')
cy.get('button[type="submit"]').click()
})
it('should confirm new Message', () => {
cy.visit('/dashboard/messages')
cy.get('tbody > tr').should('have.length', 3)
})
})

View File

@ -0,0 +1,36 @@
/// <reference types="cypress" />
import "../support/commands"
context('Notifier Tests', () => {
beforeEach(() => {
cy.restoreLocalStorageCache();
});
afterEach(() => {
cy.saveLocalStorageCache();
});
it('should Login', () => {
cy.visit('/login')
cy.get('#username').clear().type('admin')
cy.get('#password').clear().type('admin')
cy.get('button[type="submit"]').click()
cy.get('.navbar-brand').should('contain', 'Statping')
cy.getCookies()
cy.getCookies().should('have.length', 1)
})
it('should confirm notifiers are installed', () => {
cy.visit('/dashboard/settings')
cy.get('#notifiers_tabs > a').should('have.length', 9)
cy.get('#api_key').should('not.have.value', '')
cy.get('#api_secret').should('not.have.value', '')
})
})

View File

@ -119,4 +119,9 @@ context('Services Tests', () => {
cy.get('button[type="submit"]').click()
})
it('should confirm new services', () => {
cy.visit('/dashboard/services')
cy.get(':nth-child(1) > .card-body > .table > tbody > tr').should('have.length', 9)
})
})

View File

@ -0,0 +1,94 @@
/// <reference types="cypress" />
import "../support/commands"
context('Settings Tests', () => {
beforeEach(() => {
cy.restoreLocalStorageCache();
});
afterEach(() => {
cy.saveLocalStorageCache();
});
it('should Login', () => {
cy.visit('/login')
cy.get('#username').clear().type('admin')
cy.get('#password').clear().type('admin')
cy.get('button[type="submit"]').click()
cy.get('.navbar-brand').should('contain', 'Statping')
cy.getCookies()
cy.getCookies().should('have.length', 1)
})
it('should confirm notifiers are installed', () => {
cy.visit('/dashboard/settings')
cy.get('#notifiers_tabs > a').should('have.length', 9)
cy.get('#api_key').should('not.have.value', '')
cy.get('#api_secret').should('not.have.value', '')
})
it('should update Statping settings', () => {
cy.visit('/dashboard/settings')
cy.get('#project').clear().type('Statping Cypress Tests')
cy.get('#description').clear().type('Statping can use Cypress e2e testing to make it more stable!')
cy.get('#domain').clear().type('http://localhost:8888')
cy.get('#footer').clear().type('Statping Custom Footer')
cy.get('#save_core').click()
})
it('should confirm Statping settings', () => {
cy.visit('/dashboard/settings')
cy.get('#project').should('have.value', 'Statping Cypress Tests')
cy.get('#description').should('have.value', 'Statping can use Cypress e2e testing to make it more stable!')
cy.get('#domain').should('have.value', 'http://localhost:8888')
cy.get('#footer').should('have.value', 'Statping Custom Footer')
cy.get('#api_key').should('not.have.value', '')
cy.get('#api_secret').should('not.have.value', '')
})
it('should confirm new Footer text', () => {
cy.visit('/dashboard/settings')
cy.get('.footer').should('contain', 'Statping Custom Footer')
})
it('should create Local Assets', () => {
cy.visit('/dashboard/settings')
cy.get('#v-pills-style-tab').click()
cy.get('#enable_assets').click()
cy.wait(5000)
cy.visit('/dashboard/settings')
cy.get('#v-pills-style-tab').click()
cy.get('#pills-vars-tab').click()
cy.get('#assets_dir').should('contain', 'github.com/statping/statping/assets')
})
it('should save Local Assets', () => {
cy.visit('/dashboard/settings')
cy.get('#v-pills-style-tab').click()
cy.get('#pills-vars-tab').click()
cy.wait(1000)
cy.get('.CodeMirror textarea').type('{downarrow}$example-variable: #bababa;{enter}', { force: true });
cy.get('#save_assets').click();
})
it('should delete Local Assets', () => {
cy.visit('/dashboard/settings')
cy.get('#v-pills-style-tab').click()
cy.get('#pills-vars-tab').click()
cy.get('#delete_assets').click()
})
it('should view Cache', () => {
cy.visit('/dashboard/settings')
cy.get('#v-pills-cache-tab').click()
})
})

View File

@ -54,7 +54,8 @@ context('Users Tests', () => {
it('should goto users', () => {
cy.visit('/dashboard/users')
cy.get('#users_table > tr >').should('have.length', 1)
cy.get('#users_table > tr').should('have.length', 1)
cy.get('#users_table > tr').eq(0).contains('admin')
})
it('should create new User', () => {
@ -69,7 +70,9 @@ context('Users Tests', () => {
it('should confirm new user', () => {
cy.visit('/dashboard/users')
cy.get('#users_table > tr >').should('have.length', 2)
cy.get('#users_table > tr').should('have.length', 2)
cy.get('#users_table > tr').eq(0).contains('admin')
cy.get('#users_table > tr').eq(1).contains('admin2')
})

View File

@ -4,7 +4,7 @@
<div class="text-center col-12">
<h1 class="display-5">Enable Local Assets</h1>
<span class="lead">Customize your status page design by enabling local assets. This will create a 'assets' directory containing all CSS.<p>
<button @click.prevent="createAssets" :disabled="pending" href="#" class="btn btn-primary mt-3">Enable Local Assets</button>
<button id="enable_assets" @click.prevent="createAssets" :disabled="pending" href="#" class="btn btn-primary mt-3">Enable Local Assets</button>
</p></span>
</div>
</div>
@ -33,10 +33,10 @@
</div>
<div v-if="error" class="alert alert-danger mt-3" style="white-space: pre-line;">{{error}}</div>
<button @submit.prevent="saveAssets" type="submit" class="btn btn-primary btn-block mt-2" :disabled="pending">{{pending ? "Saving..." : "Save Style"}}</button>
<button v-if="directory" @click.prevent="deleteAssets" href="#" class="btn btn-danger btn-block confirm-btn" :disabled="pending">Delete Local Assets</button>
<button id="save_assets" @submit.prevent="saveAssets" type="submit" class="btn btn-primary btn-block mt-2" :disabled="pending">{{pending ? "Saving..." : "Save Style"}}</button>
<button id="delete_assets" v-if="directory" @click.prevent="deleteAssets" href="#" class="btn btn-danger btn-block confirm-btn" :disabled="pending">Delete Local Assets</button>
<h6 class="text-muted text-monospace text-sm-center font-1 mt-3">
<h6 id="assets_dir" class="text-muted text-monospace text-sm-center font-1 mt-3">
Asset Directory: {{directory}}
</h6>
</form>

View File

@ -1,7 +1,7 @@
<template>
<div>
<h1 class="col-12 text-center pt-4 mt-4 mb-3 header-title font-6">{{$store.getters.core.name}}</h1>
<h5 class="col-12 text-center mb-5 header-desc font-3">{{$store.getters.core.description}}</h5>
<h1 id="title" class="col-12 text-center pt-4 mt-4 mb-3 header-title font-6">{{$store.getters.core.name}}</h1>
<h5 id="description" class="col-12 text-center mb-5 header-desc font-3">{{$store.getters.core.description}}</h5>
</div>
</template>

View File

@ -2,23 +2,23 @@
<form @submit.prevent="saveSettings">
<div class="form-group">
<label>Project Name</label>
<input v-model="core.name" type="text" class="form-control" placeholder="Great Uptime">
<input v-model="core.name" type="text" class="form-control" placeholder="Great Uptime" id="project">
</div>
<div class="form-group">
<label>Project Description</label>
<input v-model="core.description" type="text" class="form-control" placeholder="Great Uptime">
<input v-model="core.description" type="text" class="form-control" placeholder="Great Uptime" id="description">
</div>
<div class="form-group row">
<div class="col-8 col-sm-9">
<label>Domain</label>
<input v-model="core.domain" type="url" class="form-control">
<input v-model="core.domain" type="url" class="form-control" id="domain">
</div>
<div class="col-4 col-sm-3 mt-sm-1 mt-0">
<label class="d-inline d-sm-none">Enable CDN</label>
<label class="d-none d-sm-block">Enable CDN</label>
<span @click="core.using_cdn = !!core.using_cdn" class="switch">
<span @click="core.using_cdn = !!core.using_cdn" class="switch" id="using_cdn">
<input v-model="core.using_cdn" type="checkbox" name="using_cdn" class="switch" id="switch-normal" :checked="core.using_cdn">
<label for="switch-normal"></label>
</span>
@ -27,53 +27,16 @@
<div class="form-group">
<label>Custom Footer</label>
<textarea v-model="core.footer" rows="4" class="form-control">{{core.footer}}</textarea>
<textarea v-model="core.footer" rows="4" class="form-control" id="footer">{{core.footer}}</textarea>
<small class="form-text text-muted">HTML is allowed inside the footer</small>
</div>
<div class="form-group">
<label for="timezone">Timezone</label><span class="mt-1 small float-right">Current: {{now()}}</span>
<select v-model="core.timezone" class="form-control" id="timezone">
<option value="-12.0" >(GMT -12:00) Eniwetok, Kwajalein</option>
<option value="-11.0" >(GMT -11:00) Midway Island, Samoa</option>
<option value="-10.0" >(GMT -10:00) Hawaii</option>
<option value="-9.0" >(GMT -9:00) Alaska</option>
<option value="-8.0" selected>(GMT -8:00) Pacific Time (US &amp; Canada)</option>
<option value="-7.0" >(GMT -7:00) Mountain Time (US &amp; Canada)</option>
<option value="-6.0" >(GMT -6:00) Central Time (US &amp; Canada), Mexico City</option>
<option value="-5.0" >(GMT -5:00) Eastern Time (US &amp; Canada), Bogota, Lima</option>
<option value="-4.0" >(GMT -4:00) Atlantic Time (Canada), Caracas, La Paz</option>
<option value="-3.5" >(GMT -3:30) Newfoundland</option>
<option value="-3.0" >(GMT -3:00) Brazil, Buenos Aires, Georgetown</option>
<option value="-2.0" >(GMT -2:00) Mid-Atlantic</option>
<option value="-1.0" >(GMT -1:00 hour) Azores, Cape Verde Islands</option>
<option value="0.0" >(GMT) Western Europe Time, London, Lisbon, Casablanca</option>
<option value="1.0" >(GMT +1:00 hour) Brussels, Copenhagen, Madrid, Paris</option>
<option value="2.0" >(GMT +2:00) Kaliningrad, South Africa</option>
<option value="3.0" >(GMT +3:00) Baghdad, Riyadh, Moscow, St. Petersburg</option>
<option value="3.5" >(GMT +3:30) Tehran</option>
<option value="4.0" >(GMT +4:00) Abu Dhabi, Muscat, Baku, Tbilisi</option>
<option value="4.5" >(GMT +4:30) Kabul</option>
<option value="5.0" >(GMT +5:00) Ekaterinburg, Islamabad, Karachi, Tashkent</option>
<option value="5.5" >(GMT +5:30) Bombay, Calcutta, Madras, New Delhi</option>
<option value="5.75" >(GMT +5:45) Kathmandu</option>
<option value="6.0" >(GMT +6:00) Almaty, Dhaka, Colombo</option>
<option value="7.0" >(GMT +7:00) Bangkok, Hanoi, Jakarta</option>
<option value="8.0" >(GMT +8:00) Beijing, Perth, Singapore, Hong Kong</option>
<option value="9.0" >(GMT +9:00) Tokyo, Seoul, Osaka, Sapporo, Yakutsk</option>
<option value="9.5" >(GMT +9:30) Adelaide, Darwin</option>
<option value="10.0" >(GMT +10:00) Eastern Australia, Guam, Vladivostok</option>
<option value="11.0" >(GMT +11:00) Magadan, Solomon Islands, New Caledonia</option>
<option value="12.0" >(GMT +12:00) Auckland, Wellington, Fiji, Kamchatka</option>
</select>
</div>
<button @click.prevent="saveSettings" type="submit" class="btn btn-primary btn-block">Save Settings</button>
<button @click.prevent="saveSettings" id="save_core" type="submit" class="btn btn-primary btn-block">Save Settings</button>
<div class="form-group row mt-5">
<label class="col-sm-3 col-form-label">API Key</label>
<div class="col-sm-9">
<input v-model="core.api_key" @focus="$event.target.select()" type="text" class="form-control select-input" readonly>
<input v-model="core.api_key" @focus="$event.target.select()" type="text" class="form-control select-input" id="api_key" readonly>
<small class="form-text text-muted">API Key can be used for read only routes</small>
</div>
</div>
@ -81,7 +44,7 @@
<div class="form-group row">
<label class="col-sm-3 col-form-label">API Secret</label>
<div class="col-sm-9">
<input v-model="core.api_secret" @focus="$event.target.select()" type="text" class="form-control select-input" readonly>
<input v-model="core.api_secret" @focus="$event.target.select()" type="text" class="form-control select-input" id="api_secret" readonly>
<small class="form-text text-muted">API Secret is used for read, create, update and delete routes</small>
<small class="form-text text-muted">You can <a href="#" @click="renewApiKeys">Regenerate API Keys</a> if you need to.</small>
</div>
@ -126,11 +89,12 @@
export default {
name: 'CoreSettings',
data() {
return {
core: this.$store.getters.core,
}
},
props: {
core: {
type: Object,
required: true,
}
},
methods: {
async saveSettings() {
const c = this.core

View File

@ -22,6 +22,11 @@
async mounted() {
const core = await Api.core()
this.$store.commit('setAdmin', core.admin)
this.$store.commit('setCore', core)
},
async created() {
const core = await Api.core()
this.$store.commit('setCore', core)
}
}
</script>

View File

@ -17,10 +17,12 @@
<h6 class="mt-4 text-muted">Notifiers</h6>
<a v-for="(notifier, index) in $store.getters.notifiers" v-bind:key="`${notifier.method}_${index}`" @click.prevent="changeTab" class="nav-link text-capitalize" v-bind:class="{active: liClass(`v-pills-${notifier.method.toLowerCase()}-tab`)}" v-bind:id="`v-pills-${notifier.method.toLowerCase()}-tab`" data-toggle="pill" v-bind:href="`#v-pills-${notifier.method.toLowerCase()}`" role="tab" v-bind:aria-controls="`v-pills-${notifier.method.toLowerCase()}`" aria-selected="false">
<font-awesome-icon :icon="iconName(notifier.icon)" class="mr-2"/> {{notifier.method}}
<span v-if="notifier.enabled" class="badge badge-pill float-right mt-1" :class="{'badge-success': !liClass(`v-pills-${notifier.method.toLowerCase()}-tab`), 'badge-light': liClass(`v-pills-${notifier.method.toLowerCase()}-tab`), 'text-dark': liClass(`v-pills-${notifier.method.toLowerCase()}-tab`)}">ON</span>
</a>
<div id="notifiers_tabs">
<a v-for="(notifier, index) in $store.getters.notifiers" v-bind:key="`${notifier.method}_${index}`" @click.prevent="changeTab" class="nav-link text-capitalize" v-bind:class="{active: liClass(`v-pills-${notifier.method.toLowerCase()}-tab`)}" v-bind:id="`v-pills-${notifier.method.toLowerCase()}-tab`" data-toggle="pill" v-bind:href="`#v-pills-${notifier.method.toLowerCase()}`" role="tab" v-bind:aria-controls="`v-pills-${notifier.method.toLowerCase()}`" aria-selected="false">
<font-awesome-icon :icon="iconName(notifier.icon)" class="mr-2"/> {{notifier.method}}
<span v-if="notifier.enabled" class="badge badge-pill float-right mt-1" :class="{'badge-success': !liClass(`v-pills-${notifier.method.toLowerCase()}-tab`), 'badge-light': liClass(`v-pills-${notifier.method.toLowerCase()}-tab`), 'text-dark': liClass(`v-pills-${notifier.method.toLowerCase()}-tab`)}">ON</span>
</a>
</div>
</div>
</div>
@ -33,7 +35,7 @@
<div class="card-header">Statping Settings</div>
<div class="card-body">
<CoreSettings/>
<CoreSettings :core="core"/>
</div>
</div>
@ -120,12 +122,12 @@
this.cache = await Api.cache()
},
async created() {
const c = this.$store.getters.core
const c = this.$store.state.core
this.qrurl = `statping://setup?domain=${c.domain}&api=${c.api_secret}`
this.qrcode = "https://chart.googleapis.com/chart?chs=500x500&cht=qr&chl=" + encodeURI(this.qrurl)
},
beforeMount() {
async beforeMount() {
this.core = await Api.core()
},
methods: {
changeTab(e) {