Fix cypress tests

This commit is contained in:
Andrew Kingston 2020-10-27 15:26:07 +00:00
parent bf14c3045d
commit a93757a8d9
15 changed files with 150 additions and 175 deletions

View File

@ -14,35 +14,26 @@ context("Create a automation", () => {
cy.createTestTableWithData() cy.createTestTableWithData()
cy.contains("automate").click() cy.contains("automate").click()
cy.contains("Create New Automation").click() cy.get("[data-cy=new-automation]").click()
cy.get(".modal").within(() => { cy.get(".modal").within(() => {
cy.get("input").type("Add Row") cy.get("input").type("Add Row")
cy.get(".buttons") cy.get(".buttons").contains("Create").click()
.contains("Create")
.click()
}) })
// Add trigger // Add trigger
cy.get("[data-cy=add-automation-component]").click() cy.contains("Trigger").click()
cy.get("[data-cy=ROW_SAVED]").click() cy.contains("Row Saved").click()
cy.get("[data-cy=automation-block-setup]").within(() => { cy.get(".setup").within(() => {
cy.get("select") cy.get("select").first().select("dog")
.first()
.select("dog")
}) })
// Create action // Create action
cy.get("[data-cy=CREATE_ROW]").click() cy.contains("Action").click()
cy.get("[data-cy=automation-block-setup]").within(() => { cy.contains("Create Row").click()
cy.get("select") cy.get(".setup").within(() => {
.first() cy.get("select").first().select("dog")
.select("dog") cy.get("input").first().type("goodboy")
cy.get("input") cy.get("input").eq(1).type("11")
.first()
.type("goodboy")
cy.get("input")
.eq(1)
.type("11")
}) })
// Save // Save
@ -50,11 +41,11 @@ context("Create a automation", () => {
// Activate Automation // Activate Automation
cy.get("[data-cy=activate-automation]").click() cy.get("[data-cy=activate-automation]").click()
cy.get(".stop-button.highlighted").should("be.visible") cy.get(".ri-stop-circle-fill.highlighted").should("be.visible")
}) })
it("should add row when a new row is added", () => { it("should add row when a new row is added", () => {
cy.contains("backend").click() cy.contains("data").click()
cy.addRow(["Rover", 15]) cy.addRow(["Rover", 15])
cy.reload() cy.reload()
cy.contains("goodboy").should("have.text", "goodboy") cy.contains("goodboy").should("have.text", "goodboy")

View File

@ -1,54 +1,60 @@
xcontext('Create Components', () => { xcontext("Create Components", () => {
before(() => {
cy.server()
cy.visit("localhost:4001/_builder")
// https://on.cypress.io/type
cy.createApp("Table App", "Table App Description")
cy.createTable("dog", "name", "age")
cy.addRow("bob", "15")
})
before(() => { // https://on.cypress.io/interacting-with-elements
cy.server() it("should add a container", () => {
cy.visit('localhost:4001/_builder') cy.navigateToFrontend()
// https://on.cypress.io/type cy.get(".switcher > :nth-child(2)").click()
cy.createApp('Table App', 'Table App Description') cy.contains("Container").click()
cy.createTable('dog', 'name', 'age') })
cy.addRow('bob', '15') it("should add a headline", () => {
}) cy.addHeadlineComponent("An Amazing headline!")
// https://on.cypress.io/interacting-with-elements getIframeBody().contains("An Amazing headline!")
it('should add a container', () => { })
cy.contains('frontend').click() it("change the font size of the headline", () => {
cy.get('.switcher > :nth-child(2)').click() cy.contains("Typography").click()
cy.get("[data-cy=font-size-prop-control]").click()
cy.contains("60px").click()
cy.contains("Design").click()
cy.contains('Container').click() getIframeBody()
}) .contains("An Amazing headline!")
it('should add a headline', () => { .should("have.css", "font-size", "60px")
cy.addHeadlineComponent('An Amazing headline!') })
getIframeBody().contains('An Amazing headline!')
})
it('change the font size of the headline', () => {
cy.contains('Typography').click()
cy.get('[data-cy=font-size-prop-control]').click()
cy.contains("60px").click()
cy.contains('Design').click()
getIframeBody().contains('An Amazing headline!').should('have.css', 'font-size', '60px')
})
}) })
const getIframeDocument = () => { const getIframeDocument = () => {
return cy return (
.get('iframe') cy
// Cypress yields jQuery element, which has the real .get("iframe")
// DOM element under property "0". // Cypress yields jQuery element, which has the real
// From the real DOM iframe element we can get // DOM element under property "0".
// the "document" element, it is stored in "contentDocument" property // From the real DOM iframe element we can get
// Cypress "its" command can access deep properties using dot notation // the "document" element, it is stored in "contentDocument" property
// https://on.cypress.io/its // Cypress "its" command can access deep properties using dot notation
.its('0.contentDocument').should('exist') // https://on.cypress.io/its
.its("0.contentDocument")
.should("exist")
)
} }
const getIframeBody = () => { const getIframeBody = () => {
// get the document // get the document
return getIframeDocument() return (
// automatically retries until body is loaded getIframeDocument()
.its('body').should('not.be.undefined') // automatically retries until body is loaded
// wraps "body" DOM element to allow .its("body")
// chaining more Cypress commands, like ".find(...)" .should("not.be.undefined")
.then(cy.wrap) // wraps "body" DOM element to allow
} // chaining more Cypress commands, like ".find(...)"
.then(cy.wrap)
)
}

View File

@ -8,7 +8,7 @@ context("Create a Table", () => {
cy.createTable("dog") cy.createTable("dog")
// Check if Table exists // Check if Table exists
cy.get(".title span").should("have.text", "dog") cy.get(".table-title h1").should("have.text", "dog")
}) })
it("adds a new column to the table", () => { it("adds a new column to the table", () => {
@ -24,9 +24,7 @@ context("Create a Table", () => {
it("updates a column on the table", () => { it("updates a column on the table", () => {
cy.contains("name").click() cy.contains("name").click()
cy.get("[data-cy='edit-column-header']").click() cy.get("[data-cy='edit-column-header']").click()
cy.get(".actions input") cy.get(".actions input").first().type("updated")
.first()
.type("updated")
// Unset table display column // Unset table display column
cy.contains("display column").click() cy.contains("display column").click()
cy.contains("Save Column").click() cy.contains("Save Column").click()
@ -56,9 +54,7 @@ context("Create a Table", () => {
}) })
it("deletes a table", () => { it("deletes a table", () => {
cy.contains("div", "dog") cy.contains(".nav-item", "dog").get(".actions").invoke("show").click()
.get(".ri-more-line")
.click()
cy.get("[data-cy=delete-table]").click() cy.get("[data-cy=delete-table]").click()
cy.contains("Delete Table").click() cy.contains("Delete Table").click()
cy.contains("dog").should("not.exist") cy.contains("dog").should("not.exist")

View File

@ -22,7 +22,7 @@ context("Create a View", () => {
cy.get("input").type("Test View") cy.get("input").type("Test View")
cy.contains("Save View").click() cy.contains("Save View").click()
}) })
cy.get(".title").contains("Test View") cy.get(".table-title h1").contains("Test View")
cy.get("thead th div").should($headers => { cy.get("thead th div").should($headers => {
expect($headers).to.have.length(3) expect($headers).to.have.length(3)
const headers = $headers.map((i, header) => Cypress.$(header).text()) const headers = $headers.map((i, header) => Cypress.$(header).text())
@ -33,14 +33,8 @@ context("Create a View", () => {
it("filters the view by age over 10", () => { it("filters the view by age over 10", () => {
cy.contains("Filter").click() cy.contains("Filter").click()
cy.contains("Add Filter").click() cy.contains("Add Filter").click()
cy.get(".menu-container") cy.get(".menu-container").find("select").first().select("age")
.find("select") cy.get(".menu-container").find("select").eq(1).select("More Than")
.first()
.select("age")
cy.get(".menu-container")
.find("select")
.eq(1)
.select("More Than")
cy.get("input").type(18) cy.get("input").type(18)
cy.contains("Save").click() cy.contains("Save").click()
cy.get("tbody tr").should($values => { cy.get("tbody tr").should($values => {
@ -52,15 +46,9 @@ context("Create a View", () => {
cy.contains("Calculate").click() cy.contains("Calculate").click()
// we may reinstate this - have commented this dropdown for now as there is only one option // we may reinstate this - have commented this dropdown for now as there is only one option
//cy.get(".menu-container").find("select").first().select("Statistics") //cy.get(".menu-container").find("select").first().select("Statistics")
cy.get(".menu-container") cy.get(".menu-container").find("select").eq(0).select("Statistics")
.find("select")
.eq(0)
.select("Statistics")
cy.wait(50) cy.wait(50)
cy.get(".menu-container") cy.get(".menu-container").find("select").eq(1).select("age")
.find("select")
.eq(1)
.select("age")
cy.contains("Save").click() cy.contains("Save").click()
cy.get("thead th div").should($headers => { cy.get("thead th div").should($headers => {
expect($headers).to.have.length(7) expect($headers).to.have.length(7)
@ -114,10 +102,11 @@ context("Create a View", () => {
}) })
it("renames a view", () => { it("renames a view", () => {
cy.contains("[data-cy=table-nav-item]", "Test View") cy.contains(".nav-item", "Test View")
.find(".ri-more-line") .find(".actions")
.invoke("show")
.click() .click()
cy.contains("Edit").click() cy.get("[data-cy=edit-view]").click()
cy.get(".menu-container").within(() => { cy.get(".menu-container").within(() => {
cy.get("input").type(" Updated") cy.get("input").type(" Updated")
cy.contains("Save").click() cy.contains("Save").click()
@ -126,11 +115,11 @@ context("Create a View", () => {
}) })
it("deletes a view", () => { it("deletes a view", () => {
cy.contains("[data-cy=table-nav-item]", "Test View Updated").click() cy.contains(".nav-item", "Test View Updated")
cy.contains("[data-cy=table-nav-item]", "Test View Updated") .find(".actions")
.find(".ri-more-line") .invoke("show")
.click() .click()
cy.contains("Delete").click() cy.get("[data-cy=delete-view]").click()
cy.contains("Delete View").click() cy.contains("Delete View").click()
cy.contains("TestView Updated").should("not.be.visible") cy.contains("TestView Updated").should("not.be.visible")
}) })

View File

@ -31,9 +31,7 @@ Cypress.Commands.add("createApp", name => {
.then($body => { .then($body => {
if ($body.find("input[name=apiKey]").length) { if ($body.find("input[name=apiKey]").length) {
// input was found, do something else here // input was found, do something else here
cy.get("input[name=apiKey]") cy.get("input[name=apiKey]").type(name).should("have.value", name)
.type(name)
.should("have.value", name)
cy.contains("Next").click() cy.contains("Next").click()
} }
}) })
@ -44,14 +42,10 @@ Cypress.Commands.add("createApp", name => {
cy.contains("Next").click() cy.contains("Next").click()
cy.get("input[name=username]") cy.get("input[name=username]").click().type("test")
.click() cy.get("input[name=password]").click().type("test")
.type("test")
cy.get("input[name=password]")
.click()
.type("test")
cy.contains("Submit").click() cy.contains("Submit").click()
cy.contains("Create New Table", { cy.get("[data-cy=new-table]", {
timeout: 20000, timeout: 20000,
}).should("be.visible") }).should("be.visible")
}) })
@ -65,28 +59,22 @@ Cypress.Commands.add("createTestTableWithData", () => {
Cypress.Commands.add("createTable", tableName => { Cypress.Commands.add("createTable", tableName => {
// Enter table name // Enter table name
cy.contains("Create New Table").click() cy.get("[data-cy=new-table]").click()
cy.get(".modal").within(() => { cy.get(".modal").within(() => {
cy.get("input") cy.get("input").first().type(tableName)
.first() cy.get(".buttons").contains("Create").click()
.type(tableName)
cy.get(".buttons")
.contains("Create")
.click()
}) })
cy.contains(tableName).should("be.visible") cy.contains(tableName).should("be.visible")
}) })
Cypress.Commands.add("addColumn", (tableName, columnName, type) => { Cypress.Commands.add("addColumn", (tableName, columnName, type) => {
// Select Table // Select Table
cy.contains(tableName).click() cy.contains(".nav-item", tableName).click()
cy.contains("Create New Column").click() cy.contains("Create New Column").click()
// Configure column // Configure column
cy.get(".menu-container").within(() => { cy.get(".menu-container").within(() => {
cy.get("input") cy.get("input").first().type(columnName)
.first()
.type(columnName)
// Unset table display column // Unset table display column
cy.contains("display column").click() cy.contains("display column").click()
cy.get("select").select(type) cy.get("select").select(type)
@ -99,15 +87,11 @@ Cypress.Commands.add("addRow", values => {
cy.get(".modal").within(() => { cy.get(".modal").within(() => {
for (let i = 0; i < values.length; i++) { for (let i = 0; i < values.length; i++) {
cy.get("input") cy.get("input").eq(i).type(values[i])
.eq(i)
.type(values[i])
} }
// Save // Save
cy.get(".buttons") cy.get(".buttons").contains("Create").click()
.contains("Create")
.click()
}) })
}) })
@ -116,20 +100,12 @@ Cypress.Commands.add("createUser", (username, password, accessLevel) => {
cy.get(".toprightnav > .settings").click() cy.get(".toprightnav > .settings").click()
cy.contains("Users").click() cy.contains("Users").click()
cy.get("[name=Name]") cy.get("[name=Name]").first().type(username)
.first() cy.get("[name=Password]").first().type(password)
.type(username) cy.get("select").first().select(accessLevel)
cy.get("[name=Password]")
.first()
.type(password)
cy.get("select")
.first()
.select(accessLevel)
// Save // Save
cy.get(".inputs") cy.get(".inputs").contains("Create").click()
.contains("Create")
.click()
}) })
Cypress.Commands.add("addHeadlineComponent", text => { Cypress.Commands.add("addHeadlineComponent", text => {
@ -149,19 +125,15 @@ Cypress.Commands.add("addButtonComponent", () => {
}) })
Cypress.Commands.add("navigateToFrontend", () => { Cypress.Commands.add("navigateToFrontend", () => {
cy.contains("frontend").click() cy.contains("design").click()
}) })
Cypress.Commands.add("createScreen", (screenName, route) => { Cypress.Commands.add("createScreen", (screenName, route) => {
cy.contains("Create New Screen").click() cy.get("[data-cy=new-screen]").click()
cy.get(".modal").within(() => { cy.get(".modal").within(() => {
cy.get("input") cy.get("input").eq(0).type(screenName)
.eq(0)
.type(screenName)
if (route) { if (route) {
cy.get("input") cy.get("input").eq(1).type(route)
.eq(1)
.type(route)
} }
cy.contains("Create Screen").click() cy.contains("Create Screen").click()
}) })

View File

@ -11,7 +11,10 @@
<div class="title"> <div class="title">
<h1>Automations</h1> <h1>Automations</h1>
<i on:click={modal.show} class="ri-add-circle-fill" /> <i
on:click={modal.show}
data-cy="new-automation"
class="ri-add-circle-fill" />
</div> </div>
<AutomationList /> <AutomationList />
<Modal bind:this={modal}> <Modal bind:this={modal}>

View File

@ -43,7 +43,7 @@
</script> </script>
<div class="table-container"> <div class="table-container">
<div class="title"> <div class="table-title">
<h1>{title}</h1> <h1>{title}</h1>
{#if loading} {#if loading}
<div transition:fade> <div transition:fade>
@ -125,19 +125,19 @@
gap: var(--spacing-l); gap: var(--spacing-l);
} }
.title { .table-title {
height: 24px; height: 24px;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: flex-start; justify-content: flex-start;
align-items: center; align-items: center;
} }
.title h1 { .table-title h1 {
font-size: var(--font-size-m); font-size: var(--font-size-m);
font-weight: 500; font-weight: 500;
margin: 0; margin: 0;
} }
.title > div { .table-title > div {
margin-left: var(--spacing-xs); margin-left: var(--spacing-xs);
} }

View File

@ -36,11 +36,16 @@
</div> </div>
<DropdownMenu bind:this={dropdown} {anchor} align="left"> <DropdownMenu bind:this={dropdown} {anchor} align="left">
<DropdownContainer> <DropdownContainer>
<DropdownItem icon="ri-edit-line" title="Edit" on:click={showModal} /> <DropdownItem
icon="ri-edit-line"
title="Edit"
on:click={showModal}
data-cy="edit-row" />
<DropdownItem <DropdownItem
icon="ri-delete-bin-line" icon="ri-delete-bin-line"
title="Delete" title="Delete"
on:click={showDelete} /> on:click={showDelete}
data-cy="delete-row" />
</DropdownContainer> </DropdownContainer>
</DropdownMenu> </DropdownMenu>
<ConfirmDialog <ConfirmDialog

View File

@ -1,10 +1,9 @@
<script> <script>
import { Heading, Body, Button, Select, Label } from "@budibase/bbui" import { Select, Label } from "@budibase/bbui"
import { notifier } from "builderStore/store/notifications" import { notifier } from "builderStore/store/notifications"
import { FIELDS } from "constants/backend" import { FIELDS } from "constants/backend"
import api from "builderStore/api" import api from "builderStore/api"
const BYTES_IN_KB = 1000
const BYTES_IN_MB = 1000000 const BYTES_IN_MB = 1000000
const FILE_SIZE_LIMIT = BYTES_IN_MB * 1 const FILE_SIZE_LIMIT = BYTES_IN_MB * 1
@ -70,15 +69,16 @@
const fileArray = Array.from(evt.target.files) const fileArray = Array.from(evt.target.files)
if (fileArray.some(file => file.size >= FILE_SIZE_LIMIT)) { if (fileArray.some(file => file.size >= FILE_SIZE_LIMIT)) {
notifier.danger( notifier.danger(
`Files cannot exceed ${FILE_SIZE_LIMIT / `Files cannot exceed ${
BYTES_IN_MB}MB. Please try again with smaller files.` FILE_SIZE_LIMIT / BYTES_IN_MB
}MB. Please try again with smaller files.`
) )
return return
} }
// Read CSV as plain text to upload alongside schema // Read CSV as plain text to upload alongside schema
let reader = new FileReader() let reader = new FileReader()
reader.addEventListener("load", function(e) { reader.addEventListener("load", function (e) {
csvString = e.target.result csvString = e.target.result
files = fileArray files = fileArray
validateCSV() validateCSV()

View File

@ -29,11 +29,9 @@
function showModal() { function showModal() {
const screens = $store.screens const screens = $store.screens
templateScreens = screens.filter( templateScreens = screens.filter(screen => screen.autoTableId === table._id)
(screen) => screen.autoTableId === table._id
)
willBeDeleted = ["All table data"].concat( willBeDeleted = ["All table data"].concat(
templateScreens.map((screen) => `Screen ${screen.props._instanceName}`) templateScreens.map(screen => `Screen ${screen.props._instanceName}`)
) )
hideEditor() hideEditor()
confirmDeleteDialog.show() confirmDeleteDialog.show()
@ -57,7 +55,7 @@
const tableName = evt.target.value const tableName = evt.target.value
if ( if (
originalName !== tableName && originalName !== tableName &&
$backendUiStore.models?.some((model) => model.name === tableName) $backendUiStore.models?.some(model => model.name === tableName)
) { ) {
error = `Table with name ${tableName} already exists. Please choose another name.` error = `Table with name ${tableName} already exists. Please choose another name.`
return return
@ -87,11 +85,16 @@
</div> </div>
{:else} {:else}
<DropdownContainer> <DropdownContainer>
<DropdownItem icon="ri-edit-line" title="Edit" on:click={showEditor} /> <DropdownItem
icon="ri-edit-line"
data-cy="edit-table"
title="Edit"
on:click={showEditor} />
<DropdownItem <DropdownItem
icon="ri-delete-bin-line" icon="ri-delete-bin-line"
title="Delete" title="Delete"
on:click={showModal} /> on:click={showModal}
data-cy="delete-table" />
</DropdownContainer> </DropdownContainer>
{/if} {/if}
</DropdownMenu> </DropdownMenu>

View File

@ -62,10 +62,15 @@
</div> </div>
{:else} {:else}
<DropdownContainer> <DropdownContainer>
<DropdownItem icon="ri-edit-line" title="Edit" on:click={showEditor} /> <DropdownItem
icon="ri-edit-line"
data-cy="edit-view"
title="Edit"
on:click={showEditor} />
<DropdownItem <DropdownItem
icon="ri-delete-bin-line" icon="ri-delete-bin-line"
title="Delete" title="Delete"
data-cy="delete-view"
on:click={showDelete} /> on:click={showDelete} />
</DropdownContainer> </DropdownContainer>
{/if} {/if}

View File

@ -5,7 +5,12 @@
export let disabled export let disabled
</script> </script>
<div class="dropdown-item" class:disabled on:click class:big={subtitle != null}> <div
class="dropdown-item"
class:disabled
on:click
class:big={subtitle != null}
{...$$restProps}>
{#if icon}<i class={icon} />{/if} {#if icon}<i class={icon} />{/if}
<div class="content"> <div class="content">
<div class="title">{title}</div> <div class="title">{title}</div>

View File

@ -11,7 +11,7 @@
</script> </script>
<div <div
class="container" class="nav-item"
class:border class:border
class:selected class:selected
style={`padding-left: ${indentLevel * 18}px`} style={`padding-left: ${indentLevel * 18}px`}
@ -42,22 +42,22 @@
</div> </div>
<style> <style>
.container { .nav-item {
border-radius: var(--border-radius-m); border-radius: var(--border-radius-m);
cursor: pointer; cursor: pointer;
color: var(--grey-7); color: var(--grey-7);
} }
.container.border { .nav-item.border {
border-top: 1px solid var(--grey-1); border-top: 1px solid var(--grey-1);
} }
.container.selected { .nav-item.selected {
background-color: var(--grey-2); background-color: var(--grey-2);
color: var(--ink); color: var(--ink);
} }
.container:hover { .nav-item:hover {
background-color: var(--grey-1); background-color: var(--grey-1);
} }
.container:hover .actions { .nav-item:hover .actions {
display: flex; display: flex;
} }

View File

@ -11,7 +11,7 @@
<div class="title"> <div class="title">
<h1>Screens</h1> <h1>Screens</h1>
<i on:click={modal.show} class="ri-add-circle-fill" /> <i on:click={modal.show} data-cy="new-screen" class="ri-add-circle-fill" />
</div> </div>
<PagesList /> <PagesList />
<div class="nav-items-container"> <div class="nav-items-container">

View File

@ -13,7 +13,7 @@
<slot /> <slot />
</div> </div>
{#if $automationStore.selectedAutomation} {#if $automationStore.selectedAutomation}
<div class="nav"> <div class="nav setup">
<SetupPanel /> <SetupPanel />
</div> </div>
{/if} {/if}