Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI tests #1126

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 40 additions & 24 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,32 +17,48 @@ jobs:
runs-on: [self-hosted, tartelet]
steps:
- uses: actions/checkout@v2
- name: Run tests on iOS Simulator
# - name: Run tests on iOS Simulator
# shell: bash
# run: |
# sudo xcode-select --switch /Applications/Xcode_14.3.app
# xcodebuild -scheme BuiltinRegistryGenerator -destination "platform=macOS"
# xcodebuild test -scheme LiveViewNative-Package -sdk iphonesimulator16.4 -destination "OS=16.4,name=iPhone 14 Pro" -enableCodeCoverage YES -resultBundlePath TestResults
# - uses: kishikawakatsumi/xcresulttool@v1
# with:
# path: TestResults.xcresult
# continue-on-error: true
# if: success() || failure()
# - name: Validate Coverage %
# shell: bash
# run: |
# COVERAGE=$(xcrun xccov view --report --json TestResults.xcresult | jq '.targets[] | select(.name == "LiveViewNative") | .lineCoverage')
# if [ $(echo "$COVERAGE > $MIN_COVERAGE" | bc) -ne 1 ]; then
# printf "Code coverage $COVERAGE does not meet minimum requirement $MIN_COVERAGE"
# exit -1
# else
# printf "Code coverage $COVERAGE meets minimum requirement $MIN_COVERAGE"
# fi
# - name: Build for macOS
# shell: bash
# run: |
# xcodebuild -scheme LiveViewNative-Package -sdk macosx13.3 -destination "platform=macOS"
# - name: Build for watchOS
# shell: bash
# run: |
# xcodebuild -scheme LiveViewNative-Package -sdk watchsimulator9.4 -destination "OS=9.4,name=Apple Watch Series 8 (45mm)"
- name: Set up Elixir
shell: bash
run: |
sudo xcode-select --switch /Applications/Xcode_14.3.app
xcodebuild -scheme BuiltinRegistryGenerator -destination "platform=macOS"
xcodebuild test -scheme LiveViewNative-Package -sdk iphonesimulator16.4 -destination "OS=16.4,name=iPhone 14 Pro" -enableCodeCoverage YES -resultBundlePath TestResults
brew install elixir
- name: Run integration tests on iOS Simulator
shell: bash
working-directory: Tests/IntegrationTests
run: |
cd backend && mix deps.get && mix phx.server &
cd frontend && xcodebuild -scheme BuiltinRegistryGenerator -destination "platform=macOS"
xcodebuild test -scheme frontendUITests -sdk iphonesimulator16.4 -destination "OS=16.4,name=iPhone 14 Pro" -resultBundlePath IntegrationTestResults -retry-tests-on-failure
- uses: kishikawakatsumi/xcresulttool@v1
with:
path: TestResults.xcresult
path: Tests/IntegrationTests/frontend/IntegrationTestResults.xcresult
continue-on-error: true
if: success() || failure()
- name: Validate Coverage %
shell: bash
run: |
COVERAGE=$(xcrun xccov view --report --json TestResults.xcresult | jq '.targets[] | select(.name == "LiveViewNative") | .lineCoverage')
if [ $(echo "$COVERAGE > $MIN_COVERAGE" | bc) -ne 1 ]; then
printf "Code coverage $COVERAGE does not meet minimum requirement $MIN_COVERAGE"
exit -1
else
printf "Code coverage $COVERAGE meets minimum requirement $MIN_COVERAGE"
fi
- name: Build for macOS
shell: bash
run: |
xcodebuild -scheme LiveViewNative-Package -sdk macosx13.3 -destination "platform=macOS"
- name: Build for watchOS
shell: bash
run: |
xcodebuild -scheme LiveViewNative-Package -sdk watchsimulator9.4 -destination "OS=9.4,name=Apple Watch Series 8 (45mm)"
if: success() || failure()
76 changes: 76 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
{
"configurations": [
{
"type": "lldb",
"request": "launch",
"sourceLanguages": [
"swift"
],
"name": "Debug TutorialRepoGenerator",
"program": "${workspaceFolder:liveview-client-swiftui}/.build/debug/TutorialRepoGenerator",
"args": [],
"cwd": "${workspaceFolder:liveview-client-swiftui}",
"preLaunchTask": "swift: Build Debug TutorialRepoGenerator"
},
{
"type": "lldb",
"request": "launch",
"sourceLanguages": [
"swift"
],
"name": "Release TutorialRepoGenerator",
"program": "${workspaceFolder:liveview-client-swiftui}/.build/release/TutorialRepoGenerator",
"args": [],
"cwd": "${workspaceFolder:liveview-client-swiftui}",
"preLaunchTask": "swift: Build Release TutorialRepoGenerator"
},
{
"type": "lldb",
"request": "launch",
"sourceLanguages": [
"swift"
],
"name": "Debug DocumentationExtensionGenerator",
"program": "${workspaceFolder:liveview-client-swiftui}/.build/debug/DocumentationExtensionGenerator",
"args": [],
"cwd": "${workspaceFolder:liveview-client-swiftui}",
"preLaunchTask": "swift: Build Debug DocumentationExtensionGenerator"
},
{
"type": "lldb",
"request": "launch",
"sourceLanguages": [
"swift"
],
"name": "Release DocumentationExtensionGenerator",
"program": "${workspaceFolder:liveview-client-swiftui}/.build/release/DocumentationExtensionGenerator",
"args": [],
"cwd": "${workspaceFolder:liveview-client-swiftui}",
"preLaunchTask": "swift: Build Release DocumentationExtensionGenerator"
},
{
"type": "lldb",
"request": "launch",
"sourceLanguages": [
"swift"
],
"name": "Debug BuiltinRegistryGenerator",
"program": "${workspaceFolder:liveview-client-swiftui}/.build/debug/BuiltinRegistryGenerator",
"args": [],
"cwd": "${workspaceFolder:liveview-client-swiftui}",
"preLaunchTask": "swift: Build Debug BuiltinRegistryGenerator"
},
{
"type": "lldb",
"request": "launch",
"sourceLanguages": [
"swift"
],
"name": "Release BuiltinRegistryGenerator",
"program": "${workspaceFolder:liveview-client-swiftui}/.build/release/BuiltinRegistryGenerator",
"args": [],
"cwd": "${workspaceFolder:liveview-client-swiftui}",
"preLaunchTask": "swift: Build Release BuiltinRegistryGenerator"
}
]
}
25 changes: 17 additions & 8 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@
"version" : "1.2.2"
}
},
{
"identity" : "swift-async-algorithms",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-async-algorithms",
"state" : {
"revision" : "9cfed92b026c524674ed869a4ff2dcfdeedf8a2a",
"version" : "0.1.0"
}
},
{
"identity" : "swift-cmark",
"kind" : "remoteSourceControl",
Expand All @@ -28,21 +37,21 @@
}
},
{
"identity" : "swift-markdown",
"identity" : "swift-collections",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-markdown.git",
"location" : "https://github.com/apple/swift-collections.git",
"state" : {
"branch" : "main",
"revision" : "3d4b36cff09f785adf5efb190d458a3d44e6df87"
"revision" : "937e904258d22af6e447a0b72c0bc67583ef64a2",
"version" : "1.0.4"
}
},
{
"identity" : "swift-syntax",
"identity" : "swift-markdown",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-syntax.git",
"location" : "https://github.com/apple/swift-markdown.git",
"state" : {
"revision" : "2e3c42cf38defd998c87ecfe8df138f925d22736",
"version" : "509.0.0-swift-DEVELOPMENT-SNAPSHOT-2023-08-15-a"
"branch" : "main",
"revision" : "3d4b36cff09f785adf5efb190d458a3d44e6df87"
}
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,8 @@ public class LiveSessionCoordinator<R: RootRegistry>: ObservableObject {
// If there is nothing to replace, change the root URL.
if !navigationPath.isEmpty {
navigationPath[navigationPath.count - 1] = entry
} else {
self.url = redirect.to
}
}
try await coordinator.connect(domValues: self.domValues, redirect: true)
Expand All @@ -378,6 +380,7 @@ public class LiveSessionCoordinator<R: RootRegistry>: ObservableObject {
// If there is nothing to replace, change the root URL.
if navigationPath.isEmpty {
rootCoordinator.url = redirect.to
self.url = redirect.to
try await rootCoordinator.connect(domValues: self.domValues, redirect: true)
} else {
navigationPath.removeLast()
Expand All @@ -401,6 +404,8 @@ public class LiveSessionCoordinator<R: RootRegistry>: ObservableObject {
// If there is nothing to replace, change the root URL.
if !navigationPath.isEmpty {
navigationPath[navigationPath.count - 1] = entry
} else {
self.url = redirect.to
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion Sources/LiveViewNative/LiveView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,9 @@ public struct LiveView<R: RootRegistry>: View {
}

private var navigationRoot: some View {
NavStackEntryView(.init(url: storage.session.url, coordinator: rootCoordinator))
NavStackEntryView(
.init(url: storage.session.url, coordinator: rootCoordinator)
)
}
}

Expand Down
5 changes: 5 additions & 0 deletions Tests/IntegrationTests/backend/.formatter.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[
import_deps: [:phoenix],
plugins: [Phoenix.LiveView.HTMLFormatter],
inputs: ["*.{heex,ex,exs}", "{config,lib,test}/**/*.{heex,ex,exs}"]
]
37 changes: 37 additions & 0 deletions Tests/IntegrationTests/backend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# The directory Mix will write compiled artifacts to.
/_build/

# If you run "mix test --cover", coverage assets end up here.
/cover/

# The directory Mix downloads your dependencies sources to.
/deps/

# Where 3rd-party dependencies like ExDoc output generated docs.
/doc/

# Ignore .fetch files in case you like to edit your project deps locally.
/.fetch

# If the VM crashes, it generates a dump, let's ignore it too.
erl_crash.dump

# Also ignore archive artifacts (built via "mix archive.build").
*.ez

# Temporary files, for example, from tests.
/tmp/

# Ignore package tarball (built via "mix hex.build").
backend-*.tar

# Ignore assets that are produced by build tools.
/priv/static/assets/

# Ignore digested assets cache.
/priv/static/cache_manifest.json

# In case you use Node.js/npm, you want to ignore these.
npm-debug.log
/assets/node_modules/

18 changes: 18 additions & 0 deletions Tests/IntegrationTests/backend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Backend

To start your Phoenix server:

* Run `mix setup` to install and setup dependencies
* Start Phoenix endpoint with `mix phx.server` or inside IEx with `iex -S mix phx.server`

Now you can visit [`localhost:4000`](http://localhost:4000) from your browser.

Ready to run in production? Please [check our deployment guides](https://hexdocs.pm/phoenix/deployment.html).

## Learn more

* Official website: https://www.phoenixframework.org/
* Guides: https://hexdocs.pm/phoenix/overview.html
* Docs: https://hexdocs.pm/phoenix
* Forum: https://elixirforum.com/c/phoenix-forum
* Source: https://github.com/phoenixframework/phoenix
41 changes: 41 additions & 0 deletions Tests/IntegrationTests/backend/assets/js/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// If you want to use Phoenix channels, run `mix help phx.gen.channel`
// to get started and then uncomment the line below.
// import "./user_socket.js"

// You can include dependencies in two ways.
//
// The simplest option is to put them in assets/vendor and
// import them using relative paths:
//
// import "../vendor/some-package.js"
//
// Alternatively, you can `npm install some-package --prefix assets` and import
// them using a path starting with the package name:
//
// import "some-package"
//

// Include phoenix_html to handle method=PUT/DELETE in forms and buttons.
import "phoenix_html"
// Establish Phoenix Socket and LiveView configuration.
import {Socket} from "phoenix"
import {LiveSocket} from "phoenix_live_view"
import topbar from "../vendor/topbar"

let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
let liveSocket = new LiveSocket("/live", Socket, {params: {_csrf_token: csrfToken}})

// Show progress bar on live navigation and form submits
topbar.config({barColors: {0: "#29d"}, shadowColor: "rgba(0, 0, 0, .3)"})
window.addEventListener("phx:page-loading-start", _info => topbar.show(300))
window.addEventListener("phx:page-loading-stop", _info => topbar.hide())

// connect if there are any LiveViews on the page
liveSocket.connect()

// expose liveSocket on window for web console debug logs and latency simulation:
// >> liveSocket.enableDebug()
// >> liveSocket.enableLatencySim(1000) // enabled for duration of browser session
// >> liveSocket.disableLatencySim()
window.liveSocket = liveSocket

Loading