Skip to content

Commit

Permalink
Add integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
c3er committed Jul 5, 2023
1 parent 332c35d commit fd488d2
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 11 deletions.
8 changes: 7 additions & 1 deletion app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,13 @@
</div>
<div class="dialog-buttons">
<button id="search-ok-button" value="search-dialog-default">OK</button>
<button value="search-dialog-cancel" formmethod="dialog">Cancel</button>
<button
id="search-cancel-button"
value="search-dialog-cancel"
formmethod="dialog"
>
Cancel
</button>
</div>
</form>
</dialog>
Expand Down
9 changes: 9 additions & 0 deletions app/lib/search/searchMain.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
const ipc = require("../ipc/ipcMain")
const menu = require("../main/menu")

const shared = require("./searchShared")

const FIND_MENU_ID = "find"
const FIND_NEXT_MENU_ID = "find-next"
const FIND_PREVIOUS_MENU_ID = "find-previous"

let _mainMenu

exports.FIND_MENU_ID = FIND_MENU_ID

exports.FIND_NEXT_MENU_ID = FIND_NEXT_MENU_ID

exports.FIND_PREVIOUS_MENU_ID = FIND_PREVIOUS_MENU_ID

exports.SEARCH_RESULT_CLASS = shared.SEARCH_RESULT_CLASS

exports.SELECTED_SEARCH_RESULT_ID = shared.SELECTED_SEARCH_RESULT_ID

exports.init = mainMenu => {
_mainMenu = mainMenu

Expand Down
16 changes: 8 additions & 8 deletions app/lib/search/searchRenderer.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
const ipc = require("../ipc/ipcRenderer")
const renderer = require("../renderer/common")

const SEARCH_RESULT_CLASS = "search-result"
const SELECTED_SEARCH_RESULT_ID = "selected-search-result"
const shared = require("./searchShared")

const CANCEL_VALUE = "search-dialog-cancel"

const RESULT_START_TAG = `<span class="${SEARCH_RESULT_CLASS}">`
const RESULT_START_TAG = `<span class="${shared.SEARCH_RESULT_CLASS}">`
const END_TAG = "</span>"

let _document
Expand Down Expand Up @@ -130,12 +130,12 @@ exports.highlightTerm = () => {
termRegex,
RESULT_START_TAG + _term + END_TAG,
)
const searchResultElements = _document.getElementsByClassName(SEARCH_RESULT_CLASS)
const searchResultElements = _document.getElementsByClassName(shared.SEARCH_RESULT_CLASS)
_searchResultCount = searchResultElements.length
for (let i = 0; i < _searchResultCount; i++) {
const searchResult = searchResultElements[i]
if (i === _searchIndex) {
searchResult.setAttribute("id", SELECTED_SEARCH_RESULT_ID)
searchResult.setAttribute("id", shared.SELECTED_SEARCH_RESULT_ID)
} else {
searchResult.removeAttribute("id")
}
Expand All @@ -147,7 +147,7 @@ exports.scrollToResult = () => {
return
}

const resultElement = _document.getElementById(SELECTED_SEARCH_RESULT_ID)
const resultElement = _document.getElementById(shared.SELECTED_SEARCH_RESULT_ID)
const resultElementPosition = renderer.elementYPosition(resultElement)

const contentElement = renderer.contentElement()
Expand All @@ -166,9 +166,9 @@ exports.deactivate = deactivate

// For testing

exports.SEARCH_RESULT_CLASS = SEARCH_RESULT_CLASS
exports.SEARCH_RESULT_CLASS = shared.SEARCH_RESULT_CLASS

exports.SELECTED_SEARCH_RESULT_ID = SELECTED_SEARCH_RESULT_ID
exports.SELECTED_SEARCH_RESULT_ID = shared.SELECTED_SEARCH_RESULT_ID

exports.CANCEL_VALUE = CANCEL_VALUE

Expand Down
3 changes: 3 additions & 0 deletions app/lib/search/searchShared.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
exports.SEARCH_RESULT_CLASS = "search-result"

exports.SELECTED_SEARCH_RESULT_ID = "selected-search-result"
1 change: 1 addition & 0 deletions app/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ function createMainMenu() {
{
label: "&Find...",
accelerator: "CmdOrCtrl+F",
id: search.FIND_MENU_ID,
click() {
search.start()
},
Expand Down
71 changes: 69 additions & 2 deletions test/integrationSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,9 @@ function hasUnblockedContentMessage() {
}

async function elementIsHidden(page, elementPath) {
const locator = await page.locator(elementPath)
const locator = page.locator(elementPath)
await locator.waitFor({ state: "hidden" })
return locator.isHidden()
return await locator.isHidden()
}

describe("Integration tests with single app instance", () => {
Expand Down Expand Up @@ -404,6 +404,73 @@ describe("Integration tests with their own app instance each", () => {
})
})

describe("Search dialog", () => {
const search = require("../app/lib/search/searchMain")

const searchResultClass = `class="${search.SEARCH_RESULT_CLASS}"`
const selectedSearchResultId = `id="${search.SELECTED_SEARCH_RESULT_ID}"`

async function assertDialogIsClosed() {
assert.isTrue(await elementIsHidden(page, mocking.elements.searchDialog.path))
}

async function opendDialog() {
await clickMenuItem(app, search.FIND_MENU_ID)
assert.isTrue(await page.locator(mocking.elements.searchDialog.path).isVisible())
}

async function confirmDialog() {
await page.locator(mocking.elements.searchDialog.okButton.path).click()
await assertDialogIsClosed()
}

async function getContent() {
return await page.locator(mocking.elements.content.path).innerHTML()
}

async function enterSearchTerm(term) {
await page.locator(mocking.elements.searchDialog.inputField.path).fill(term)
}

it("can be canceled", async () => {
await opendDialog()
await page.locator(mocking.elements.searchDialog.cancelButton.path).click()
await assertDialogIsClosed()
})

it("changes nothing after confirming without input", async () => {
await opendDialog()
await confirmDialog()

const content = await getContent()
assert.notInclude(content, searchResultClass)
assert.notInclude(content, selectedSearchResultId)
})

it("highlights and scrolls to search term", async () => {
// It would be cleaner, if this were two tests, but every integration test takes
// quite some time.

const contentLocator = page.locator(
`${mocking.elements.content.path} > p:first-of-type`,
)
const orig = await contentLocator.boundingBox()

await opendDialog()
await enterSearchTerm("multi markdown table")
await confirmDialog()
await page.locator(`#${search.SELECTED_SEARCH_RESULT_ID}`).waitFor()

const content = await getContent()
assert.include(content, searchResultClass)
assert.include(content, selectedSearchResultId)

const changed = await contentLocator.boundingBox()
assert.strictEqual(changed.x, orig.x)
assert.notStrictEqual(changed.y, orig.y)
})
})

describe("Keyboard handling", () => {
it("has focus on content", async () => {
const contentLocator = page.locator(
Expand Down
12 changes: 12 additions & 0 deletions test/mocking.js
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,18 @@ exports.elements = {
rawText: {
path: "#raw-text",
},
searchDialog: {
path: "#search-dialog",
inputField: {
path: "#search-input",
},
okButton: {
path: "#search-ok-button",
},
cancelButton: {
path: "#search-cancel-button",
},
},
}

exports.mainWindow = {
Expand Down

0 comments on commit fd488d2

Please sign in to comment.