Skip to content

Commit

Permalink
#212: adds test to click on links in the about screen
Browse files Browse the repository at this point in the history
  • Loading branch information
rladstaetter committed Apr 10, 2024
1 parent 8a9c457 commit 876636f
Show file tree
Hide file tree
Showing 16 changed files with 160 additions and 23 deletions.
11 changes: 5 additions & 6 deletions app-tests/src/test/scala/app/logorrr/steps/CanOpenFile.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,14 @@ import java.nio.file.Path
/**
* Mix in if you need to be able to open a file in your test
*/
trait CanOpenFile {
self: TestFxBaseApplicationTest =>
trait CanOpenFile extends VisibleItemActions {
self: TestFxBaseApplicationTest =>

protected def openFile(path: Path): Unit = {
waitForVisibility(UiNodes.FileMenu)
clickOn(UiNodes.FileMenu)
waitForVisibility(UiNodes.FileMenuOpenFile)
clickOn(UiNodes.FileMenuOpenFile)
waitAndClickVisibleItem(UiNodes.FileMenu)
waitAndClickVisibleItem(UiNodes.FileMenuOpenFile)
waitForVisibility(LogFileTab.uiNode(FileId(path)))
}

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package app.logorrr.steps

import app.logorrr.usecases.TestFxBaseApplicationTest
import app.logorrr.views.UiNode
import org.testfx.api.FxRobotInterface

trait VisibleItemActions {
self: TestFxBaseApplicationTest =>

def waitAndClickVisibleItem(menu: UiNode): FxRobotInterface = {
waitForVisibility(menu)
clickOn(menu)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import app.logorrr.conf.Settings
import app.logorrr.services.LogoRRRServices
import app.logorrr.services.fileservices.OpenMultipleFilesService
import app.logorrr.services.hostservices.MockHostServices
import app.logorrr.steps.{CanOpenFile, CanStartApplication}
import app.logorrr.steps.{CanOpenFile, CanStartApplication, VisibleItemActions}

import java.nio.file.Path

Expand All @@ -16,6 +16,7 @@ import java.nio.file.Path
class MultipleFileApplicationTest(val files: Seq[Path])
extends TestFxBaseApplicationTest
with CanStartApplication
with VisibleItemActions
with CanOpenFile {

val services: LogoRRRServices = LogoRRRServices(Settings.Default
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package app.logorrr.usecases

import app.logorrr.conf.Settings
import app.logorrr.services.LogoRRRServices
import app.logorrr.services.fileservices.OpenSingleFileService
import app.logorrr.services.fileservices.{EmptyFileService, OpenSingleFileService}
import app.logorrr.services.hostservices.MockHostServices
import app.logorrr.steps.{CanOpenFile, CanStartApplication}

Expand All @@ -24,3 +24,12 @@ class SingleFileApplicationTest(val path: Path)


}

class ShowAboutDialogTest extends TestFxBaseApplicationTest with CanStartApplication {

final def services: LogoRRRServices = LogoRRRServices(Settings.Default
, new MockHostServices
, new EmptyFileService
, isUnderTest = true)

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package app.logorrr.usecases.about

import app.logorrr.conf.Settings
import app.logorrr.services.LogoRRRServices
import app.logorrr.services.fileservices.EmptyFileService
import app.logorrr.services.hostservices.MockHostServices
import app.logorrr.steps.{CanStartApplication, VisibleItemActions}
import app.logorrr.usecases.TestFxBaseApplicationTest
import app.logorrr.views.UiNodes
import app.logorrr.views.about.AboutScreen
import org.junit.jupiter.api.Test


class ShowAboutDialogTest extends TestFxBaseApplicationTest
with CanStartApplication
with VisibleItemActions {

// to get a handle to clicked urls
val mockHostServices = new MockHostServices

final def services: LogoRRRServices = {
LogoRRRServices(Settings.Default
, mockHostServices
, new EmptyFileService
, isUnderTest = true)
}


@Test def showAboutDialog(): Unit = {
waitAndClickVisibleItem(UiNodes.HelpMenu)
waitAndClickVisibleItem(UiNodes.HelpMenuAbout)

waitAndClickVisibleItem(UiNodes.AboutDialogOpenLogorrrMainSite)
waitAndClickVisibleItem(UiNodes.AboutDialogOpenDevelopmentBlog)
waitAndClickVisibleItem(UiNodes.AboutDialogOpenIssuePage)

assert(AboutScreen.links.map(_.url.toString).forall(u => mockHostServices.visitedUrls.contains(u)))
}

}
10 changes: 7 additions & 3 deletions app/src/main/scala/app/logorrr/LogoRRRApp.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import app.logorrr.io.FilePaths
import app.logorrr.meta.AppMeta
import app.logorrr.services.LogoRRRServices
import app.logorrr.services.fileservices.NativeOpenFileService
import app.logorrr.services.hostservices.NativeHostServices
import app.logorrr.util.{CanLog, JfxUtils}
import app.logorrr.services.hostservices.{MacNativeHostService, NativeHostServices}
import app.logorrr.util.{CanLog, JfxUtils, OsUtil}
import app.logorrr.views.main.{LogoRRRMain, LogoRRRStage}
import javafx.application.Application
import javafx.stage.Stage
Expand Down Expand Up @@ -49,7 +49,11 @@ object LogoRRRApp extends CanLog {
class LogoRRRApp extends javafx.application.Application with CanLog {

def start(stage: Stage): Unit = {
val hostServices = new NativeHostServices(getHostServices)
val hostServices = {
if (OsUtil.isMac) {
new MacNativeHostService
} else new NativeHostServices(getHostServices)
}


val services = logorrr.services.LogoRRRServices(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package app.logorrr.services.fileservices

import java.nio.file.Path

class EmptyFileService extends LogoRRRFileOpenService {
override def openFile: Option[Path] = None
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package app.logorrr.services.hostservices

import app.logorrr.views.UiNode

/**
* To wrap native HostServices
*/
trait LogoRRRHostServices {

/** opens given document */
def showDocument(url: String): Unit
def showDocument(uiNode: UiNode, url: String): Unit

}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package app.logorrr.services.hostservices

import app.logorrr.OsxBridge
import app.logorrr.views.UiNode

/**
* Delegate opening urls directly to native code on mac (because of apples entitlements / security system)
*/
class MacNativeHostService extends LogoRRRHostServices {
/** opens given document */
override def showDocument(uiNode: UiNode, url: String): Unit = {
OsxBridge.openUrl(url)
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
package app.logorrr.services.hostservices

import app.logorrr.util.CanLog
import app.logorrr.views.UiNode
import javafx.collections.{FXCollections, ObservableList}

class MockHostServices extends LogoRRRHostServices with CanLog {

override def showDocument(url: String): Unit = logTrace(s"showing '$url'.")
/** used for tests */
val visitedUrls: ObservableList[String] = FXCollections.observableArrayList[String]()

override def showDocument(uiNode: UiNode, url: String): Unit = {
visitedUrls.add(url)
logTrace(s"showing '$url'.")
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ package app.logorrr.services.hostservices

import app.logorrr.OsxBridge
import app.logorrr.util.OsUtil
import app.logorrr.views.UiNode
import javafx.application.HostServices


class NativeHostServices(hostServices: => HostServices) extends LogoRRRHostServices {

override def showDocument(url: String): Unit = {
override def showDocument(uiNode: UiNode, url: String): Unit = {
// hostServices.showDocument doesn't work with Entitlements / Gatekeeper
// delegate to native method
if (OsUtil.isMac) {
Expand All @@ -17,3 +19,4 @@ class NativeHostServices(hostServices: => HostServices) extends LogoRRRHostServi
}

}

13 changes: 9 additions & 4 deletions app/src/main/scala/app/logorrr/util/HLink.scala
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
package app.logorrr.util

import app.logorrr.conf.LogoRRRGlobals
import app.logorrr.views.UiNode
import javafx.scene.control.Hyperlink

import java.net.{URI, URL}

object HLink {

def apply(url: String, description: String): HLink = {
apply(URI.create(url).toURL, description)
def apply(uiNode: UiNode
, url: String
, description: String): HLink = {
apply(uiNode, URI.create(url).toURL, description)
}

}

case class HLink(url: URL
case class HLink(uiNode: UiNode
, url: URL
, description: String) {

def mkHyperLink(): Hyperlink = {
val hyperlink = new Hyperlink(description)
hyperlink.setOnAction(_ => LogoRRRGlobals.getHostServices.showDocument(url.toString))
hyperlink.setId(uiNode.value)
hyperlink.setOnAction(_ => LogoRRRGlobals.getHostServices.showDocument(uiNode, url.toString))
hyperlink
}
}
20 changes: 20 additions & 0 deletions app/src/main/scala/app/logorrr/views/UiNodes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ object UiNodes {
*/
val FileMenuCloseAll: UiNode = UiNode("file_menu_close_all")

/** help menu */
val HelpMenu: UiNode = UiNode("help_menu")


/** help menu - about */
val HelpMenuAbout: UiNode = UiNode("help_menu_about")

/** help menu - open log */
val HelpMenuOpenLogorrLog: UiNode = UiNode("help_menu_open_log")

/**
* ID of main tab pane where all log files are placed
*/
Expand All @@ -41,5 +51,15 @@ object UiNodes {
/** css rule to target the close button of a LogFileHeaderTab */
val LogFileHeaderTabCloseButton = ".tab-container > .tab-close-button"

/** open logorrrs main site */
val AboutDialogOpenLogorrrMainSite: UiNode = UiNode("about_stage_logorrr_app")

/** have a look at the development blog */
val AboutDialogOpenDevelopmentBlog: UiNode = UiNode("about_stage_devel_blog")

/** report a bug or a feature request */
val AboutDialogOpenIssuePage: UiNode = UiNode("about_stage_report_issues")

/** contains information about log formatter */
val OpenDateFormatterSite: UiNode = UiNode("date_time_formatter_url")
}
10 changes: 6 additions & 4 deletions app/src/main/scala/app/logorrr/views/about/AboutScreen.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package app.logorrr.views.about

import app.logorrr.meta.AppMeta
import app.logorrr.util.{HLink, ImageCp, LogoRRRFonts, PropsCp}
import app.logorrr.views.UiNodes
import javafx.geometry.{Insets, Pos}
import javafx.scene.control._
import javafx.scene.image.ImageView
Expand All @@ -16,10 +17,10 @@ object AboutScreen {

val logo: ImageCp = ImageCp("/app/logorrr/icon/logorrr-icon-128.png", 128, 128)

val links: Seq[HLink] = Seq(
HLink("https://www.logorrr.app/", "https://www.logorrr.app/")
, HLink("https://www.github.com/rladstaetter/LogoRRR/", "Source code")
, HLink("https://github.com/rladstaetter/LogoRRR/issues/", "Request a feature or report a bug"))
lazy val links: Seq[HLink] = Seq(
HLink(UiNodes.AboutDialogOpenLogorrrMainSite, "https://www.logorrr.app/", "https://www.logorrr.app/")
, HLink(UiNodes.AboutDialogOpenDevelopmentBlog, "https://www.logorrr.app/posts/index.html", "Development blog")
, HLink(UiNodes.AboutDialogOpenIssuePage, "https://github.com/rladstaetter/LogoRRR/issues/", "Request a feature or report a bug"))

case class MonoLabel(text: String, size: Int) extends Label(text) {
setStyle(LogoRRRFonts.jetBrainsMono(size))
Expand All @@ -44,6 +45,7 @@ object BuildProps {
}

class BuildProps {

lazy val buildProps: Properties = PropsCp("/build.properties").asProperties(getClass)

lazy val githash: String = buildProps.getProperty("revision")
Expand Down
6 changes: 6 additions & 0 deletions app/src/main/scala/app/logorrr/views/menubar/HelpMenu.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package app.logorrr.views.menubar

import app.logorrr.io.{FileId, FilePaths}
import app.logorrr.meta.AppMeta
import app.logorrr.views.UiNodes
import app.logorrr.views.about.AboutScreen
import app.logorrr.views.menubar.HelpMenu.{AboutMenuItem, LogMenuItem}
import javafx.scene.Scene
Expand All @@ -11,12 +12,16 @@ import javafx.stage.{Modality, Stage}
object HelpMenu {

class LogMenuItem(openLogFile: FileId => Unit) extends MenuItem("Open LogoRRRs log") {
setId(UiNodes.HelpMenuOpenLogorrLog.value)

setOnAction(_ => {
openLogFile(FileId(FilePaths.logFilePath))
})
}

class AboutMenuItem extends MenuItem("About") {
setId(UiNodes.HelpMenuAbout.value)

setOnAction(_ => {
val stage = new Stage()
stage.initModality(Modality.APPLICATION_MODAL)
Expand All @@ -30,5 +35,6 @@ object HelpMenu {
}

class HelpMenu(openFile: FileId => Unit) extends Menu("Help") {
setId(UiNodes.HelpMenu.value)
getItems.addAll(new LogMenuItem(openFile), new AboutMenuItem())
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package app.logorrr.views.settings.timer
import app.logorrr.conf.mut.MutLogFileSettings
import app.logorrr.model.{LogEntry, LogEntryInstantFormat}
import app.logorrr.util.{CanLog, HLink}
import app.logorrr.views.UiNodes
import javafx.beans.binding.Bindings
import javafx.beans.property.SimpleObjectProperty
import javafx.collections.ObservableList
Expand All @@ -12,7 +13,8 @@ import javafx.scene.layout.{BorderPane, VBox}

object TimerSettingsBorderPane {

private val dateTimeFormatterLink: HLink = HLink("https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html", "format description")

private val dateTimeFormatterLink: HLink = HLink(UiNodes.OpenDateFormatterSite,"https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html", "format description")

def mkTf(name: String
, somePrompt: Option[String]
Expand Down

0 comments on commit 876636f

Please sign in to comment.