analytics/test/plausible_web/live/goal_settings_test.exs

253 lines
8.3 KiB
Elixir
Raw Normal View History

Improve goal settings UX (#3293) * Add Heroicons dependency * Add name_of/1 html helper Currently with Floki there's no way to query for `[name=foo[some]]` selector * Update changelog * Make goal deletion possible with only goal id * Remove stale goal controllers * Improve ComboBox component - make sure the list options are always of the parent input width - allow passing a suggestion function instead of a module * Stale fixup * Update routes * Use the new goals route in funnel settings * Use a function in the funnel combo * Use function in the props combo * Remove old goals form * Implement new goal settings * Update moduledoc * Fix revenue switch in dark mode * Connect live socket on goal settings page * Fixup * Use Heroicons.trash icon * Tweak goals search input * Remove unused alias * Fix search/button alignment * Fix backspace icon alignment * Delegate :superadmin check to get_for_user/3 I'll do props settings separately, it's work in progress in a branch on top of this one already. cc @ukutaht * Rename socket assigns * Fixup to 5c9f58e * Fixup * Render ComboBox suggestions asynchronously This commit: - prevents redundant work by checking the socket connection - allows passing no options to the ComboBox component, so that when combined with the `async` option, the options are asynchronously initialized post-render - allows updating the suggestions asynchronously with the `async` option set to `true` - helpful in case of DB queries used for suggestions * Update tests * Throttle comboboxes * Update tests * Dim the search input * Use debounce=200 in ComboBox component * Move creatable option to the top * Ensure there's always a leading slash for goals * Test pageview goals with leading / missing * Make the modal scrollable on small viewports
2023-09-04 14:44:22 +03:00
defmodule PlausibleWeb.Live.GoalSettingsTest do
use PlausibleWeb.ConnCase, async: true
import Phoenix.LiveViewTest
import Plausible.Test.Support.HTML
describe "GET /:domain/settings/goals" do
Improve goal settings UX (#3293) * Add Heroicons dependency * Add name_of/1 html helper Currently with Floki there's no way to query for `[name=foo[some]]` selector * Update changelog * Make goal deletion possible with only goal id * Remove stale goal controllers * Improve ComboBox component - make sure the list options are always of the parent input width - allow passing a suggestion function instead of a module * Stale fixup * Update routes * Use the new goals route in funnel settings * Use a function in the funnel combo * Use function in the props combo * Remove old goals form * Implement new goal settings * Update moduledoc * Fix revenue switch in dark mode * Connect live socket on goal settings page * Fixup * Use Heroicons.trash icon * Tweak goals search input * Remove unused alias * Fix search/button alignment * Fix backspace icon alignment * Delegate :superadmin check to get_for_user/3 I'll do props settings separately, it's work in progress in a branch on top of this one already. cc @ukutaht * Rename socket assigns * Fixup to 5c9f58e * Fixup * Render ComboBox suggestions asynchronously This commit: - prevents redundant work by checking the socket connection - allows passing no options to the ComboBox component, so that when combined with the `async` option, the options are asynchronously initialized post-render - allows updating the suggestions asynchronously with the `async` option set to `true` - helpful in case of DB queries used for suggestions * Update tests * Throttle comboboxes * Update tests * Dim the search input * Use debounce=200 in ComboBox component * Move creatable option to the top * Ensure there's always a leading slash for goals * Test pageview goals with leading / missing * Make the modal scrollable on small viewports
2023-09-04 14:44:22 +03:00
setup [:create_user, :log_in, :create_site]
@tag :ee_only
Improve goal settings UX (#3293) * Add Heroicons dependency * Add name_of/1 html helper Currently with Floki there's no way to query for `[name=foo[some]]` selector * Update changelog * Make goal deletion possible with only goal id * Remove stale goal controllers * Improve ComboBox component - make sure the list options are always of the parent input width - allow passing a suggestion function instead of a module * Stale fixup * Update routes * Use the new goals route in funnel settings * Use a function in the funnel combo * Use function in the props combo * Remove old goals form * Implement new goal settings * Update moduledoc * Fix revenue switch in dark mode * Connect live socket on goal settings page * Fixup * Use Heroicons.trash icon * Tweak goals search input * Remove unused alias * Fix search/button alignment * Fix backspace icon alignment * Delegate :superadmin check to get_for_user/3 I'll do props settings separately, it's work in progress in a branch on top of this one already. cc @ukutaht * Rename socket assigns * Fixup to 5c9f58e * Fixup * Render ComboBox suggestions asynchronously This commit: - prevents redundant work by checking the socket connection - allows passing no options to the ComboBox component, so that when combined with the `async` option, the options are asynchronously initialized post-render - allows updating the suggestions asynchronously with the `async` option set to `true` - helpful in case of DB queries used for suggestions * Update tests * Throttle comboboxes * Update tests * Dim the search input * Use debounce=200 in ComboBox component * Move creatable option to the top * Ensure there's always a leading slash for goals * Test pageview goals with leading / missing * Make the modal scrollable on small viewports
2023-09-04 14:44:22 +03:00
test "lists goals for the site and renders links", %{conn: conn, site: site} do
{:ok, [g1, g2, g3]} = setup_goals(site)
conn = get(conn, "/#{site.domain}/settings/goals")
resp = html_response(conn, 200)
assert resp =~ "Define actions that you want your users to take"
assert resp =~ "compose Goals into Funnels"
assert resp =~ "/#{URI.encode_www_form(site.domain)}/settings/funnels"
Improve goal settings UX (#3293) * Add Heroicons dependency * Add name_of/1 html helper Currently with Floki there's no way to query for `[name=foo[some]]` selector * Update changelog * Make goal deletion possible with only goal id * Remove stale goal controllers * Improve ComboBox component - make sure the list options are always of the parent input width - allow passing a suggestion function instead of a module * Stale fixup * Update routes * Use the new goals route in funnel settings * Use a function in the funnel combo * Use function in the props combo * Remove old goals form * Implement new goal settings * Update moduledoc * Fix revenue switch in dark mode * Connect live socket on goal settings page * Fixup * Use Heroicons.trash icon * Tweak goals search input * Remove unused alias * Fix search/button alignment * Fix backspace icon alignment * Delegate :superadmin check to get_for_user/3 I'll do props settings separately, it's work in progress in a branch on top of this one already. cc @ukutaht * Rename socket assigns * Fixup to 5c9f58e * Fixup * Render ComboBox suggestions asynchronously This commit: - prevents redundant work by checking the socket connection - allows passing no options to the ComboBox component, so that when combined with the `async` option, the options are asynchronously initialized post-render - allows updating the suggestions asynchronously with the `async` option set to `true` - helpful in case of DB queries used for suggestions * Update tests * Throttle comboboxes * Update tests * Dim the search input * Use debounce=200 in ComboBox component * Move creatable option to the top * Ensure there's always a leading slash for goals * Test pageview goals with leading / missing * Make the modal scrollable on small viewports
2023-09-04 14:44:22 +03:00
assert element_exists?(resp, ~s|a[href="https://plausible.io/docs/goal-conversions"]|)
assert resp =~ to_string(g1)
assert resp =~ "Pageview"
assert resp =~ to_string(g2)
assert resp =~ "Custom Event"
assert resp =~ to_string(g3)
Rework settings UI (#4626) * Update generic components library * Import generic components via `PlausibleWeb` * Update Settings/Danger Zone * Update new shared link template and convert to heex * Update site settings layout * Update site settings sidebar tab layout * Update Settings/Email Reports * Update Funnels * Update ComboBox * Extend/update form components * Update Modal live component * Update Settings/Goals * Update Shields * Update Settings/Props * Update Settings/Import & Export * Update flow progress * Import Routes in settings * Update Billing components * Update Billing notice component * Update feature toggle component * Update 2fa component * Update verification markup * Update installation * Update Settings/Integrations/Plugins * Update domain change markup * Update Settings/General * Update Settings/Integrations * Update Settings/People * Update Settings/Integrations/GSC * Update Settings/Visiblity * ukuwip * ukuwip * Tables & paddings * Imports exports * Brighten disabled input text color for dark mode * Tune down table border/divider in dark mode * Format * Fix goal list on mobile * Fix IP Shields table on mobile * Fix country shields list on mobile * Fix country shield list on mobile * Fix page shields list on mobile * Fix import/export settings on mobile * Fix combobox dropdown background in dark mode * Fix filter bar search input on mobile * Revert @ukutaht's changes to goal list * Maybe maybe maybe * Revert the current prod goal list + fix mobile issues * Format * Revert tests change cc @ukutaht * Fix markup expectation in a test * Set autocomplete="off" again * Bring back `text-sm` where previously removed --------- Co-authored-by: Uku Taht <uku.taht@gmail.com>
2024-10-02 12:05:21 +03:00
assert resp =~ "Revenue Goal (EUR)"
Improve goal settings UX (#3293) * Add Heroicons dependency * Add name_of/1 html helper Currently with Floki there's no way to query for `[name=foo[some]]` selector * Update changelog * Make goal deletion possible with only goal id * Remove stale goal controllers * Improve ComboBox component - make sure the list options are always of the parent input width - allow passing a suggestion function instead of a module * Stale fixup * Update routes * Use the new goals route in funnel settings * Use a function in the funnel combo * Use function in the props combo * Remove old goals form * Implement new goal settings * Update moduledoc * Fix revenue switch in dark mode * Connect live socket on goal settings page * Fixup * Use Heroicons.trash icon * Tweak goals search input * Remove unused alias * Fix search/button alignment * Fix backspace icon alignment * Delegate :superadmin check to get_for_user/3 I'll do props settings separately, it's work in progress in a branch on top of this one already. cc @ukutaht * Rename socket assigns * Fixup to 5c9f58e * Fixup * Render ComboBox suggestions asynchronously This commit: - prevents redundant work by checking the socket connection - allows passing no options to the ComboBox component, so that when combined with the `async` option, the options are asynchronously initialized post-render - allows updating the suggestions asynchronously with the `async` option set to `true` - helpful in case of DB queries used for suggestions * Update tests * Throttle comboboxes * Update tests * Dim the search input * Use debounce=200 in ComboBox component * Move creatable option to the top * Ensure there's always a leading slash for goals * Test pageview goals with leading / missing * Make the modal scrollable on small viewports
2023-09-04 14:44:22 +03:00
end
@tag :ee_only
test "lists Revenue Goals with feature availability annotation if the plan does not cover them",
%{conn: conn, user: user, site: site} do
{:ok, [_, _, g3]} = setup_goals(site)
user
|> Plausible.Auth.User.end_trial()
|> Plausible.Repo.update!()
conn = get(conn, "/#{site.domain}/settings/goals")
resp = html_response(conn, 200)
assert g3.currency
assert resp =~ to_string(g3)
assert resp =~ "Unlock Revenue Goals by upgrading to a business plan"
Edit goals with display names (#4415) * Update Goal schema * Equip ComboBox with the ability of JS selection callbacks * Update factory so display_name is always present * Extend Goals context interface * Update seeds Also farming unsuspecting BEAM programmers for better sample page paths :) * Update ComboBox test * Unify error message color class with helpers seen elsewhere * Use goal.display_name where applicable * Implement LiveView extensions for editing goals * Sprinkle display name in external stats controller tests * Format * Fix goal list mobile view * Update lib/plausible_web/live/goal_settings/list.ex Co-authored-by: Artur Pata <artur.pata@gmail.com> * Update lib/plausible_web/live/goal_settings/form.ex Co-authored-by: Artur Pata <artur.pata@gmail.com> * Update the APIs: plugins and external * Update test so the intent is clearer * Format * Update CHANGELOG * Simplify form tabs tests * Revert "Format" This reverts commit c1647b53071c0423d817de6843733766276b6105. * Fixup format commit that went too far * ComboBox: select the input contents on first focus * Update lib/plausible/goal/schema.ex Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com> * Update lib/plausible/goals/goals.ex Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com> * Update lib/plausible_web/live/goal_settings/form.ex Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com> * Pass form goal instead of just ID * Make tab component dumber * Extract separate render functions for edit and create forms * Update test to account for extracted forms * Inline goal get query * Extract revenue goal settings to a component and avoid computing assigns in flight * Make LV modal preload optional * Disable preload for goal settings form modal * Get rid of phash component ID hack * For another render after render_submit when testing goal updates * Fix LV preload option * Enable preload back for goals modal for now * Make formatter happy * Implement support for preopening of LV modal * Preopen goals modal to avoid feedback gap on loading edited goal * Remove `console.log` call from modal JS * Clean up display name input IDs * Make revenue settings functional on first edit again * Display names: 2nd stage migration * Update migration with data backfill --------- Co-authored-by: Artur Pata <artur.pata@gmail.com> Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
2024-08-09 12:12:00 +03:00
refute element_exists?(
resp,
~s/button[phx-click="edit-goal"][phx-value-goal-id=#{g3.id}][disabled]#edit-goal-#{g3.id}/
)
end
Edit goals with display names (#4415) * Update Goal schema * Equip ComboBox with the ability of JS selection callbacks * Update factory so display_name is always present * Extend Goals context interface * Update seeds Also farming unsuspecting BEAM programmers for better sample page paths :) * Update ComboBox test * Unify error message color class with helpers seen elsewhere * Use goal.display_name where applicable * Implement LiveView extensions for editing goals * Sprinkle display name in external stats controller tests * Format * Fix goal list mobile view * Update lib/plausible_web/live/goal_settings/list.ex Co-authored-by: Artur Pata <artur.pata@gmail.com> * Update lib/plausible_web/live/goal_settings/form.ex Co-authored-by: Artur Pata <artur.pata@gmail.com> * Update the APIs: plugins and external * Update test so the intent is clearer * Format * Update CHANGELOG * Simplify form tabs tests * Revert "Format" This reverts commit c1647b53071c0423d817de6843733766276b6105. * Fixup format commit that went too far * ComboBox: select the input contents on first focus * Update lib/plausible/goal/schema.ex Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com> * Update lib/plausible/goals/goals.ex Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com> * Update lib/plausible_web/live/goal_settings/form.ex Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com> * Pass form goal instead of just ID * Make tab component dumber * Extract separate render functions for edit and create forms * Update test to account for extracted forms * Inline goal get query * Extract revenue goal settings to a component and avoid computing assigns in flight * Make LV modal preload optional * Disable preload for goal settings form modal * Get rid of phash component ID hack * For another render after render_submit when testing goal updates * Fix LV preload option * Enable preload back for goals modal for now * Make formatter happy * Implement support for preopening of LV modal * Preopen goals modal to avoid feedback gap on loading edited goal * Remove `console.log` call from modal JS * Clean up display name input IDs * Make revenue settings functional on first edit again * Display names: 2nd stage migration * Update migration with data backfill --------- Co-authored-by: Artur Pata <artur.pata@gmail.com> Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
2024-08-09 12:12:00 +03:00
test "lists goals with actions", %{conn: conn, site: site} do
Improve goal settings UX (#3293) * Add Heroicons dependency * Add name_of/1 html helper Currently with Floki there's no way to query for `[name=foo[some]]` selector * Update changelog * Make goal deletion possible with only goal id * Remove stale goal controllers * Improve ComboBox component - make sure the list options are always of the parent input width - allow passing a suggestion function instead of a module * Stale fixup * Update routes * Use the new goals route in funnel settings * Use a function in the funnel combo * Use function in the props combo * Remove old goals form * Implement new goal settings * Update moduledoc * Fix revenue switch in dark mode * Connect live socket on goal settings page * Fixup * Use Heroicons.trash icon * Tweak goals search input * Remove unused alias * Fix search/button alignment * Fix backspace icon alignment * Delegate :superadmin check to get_for_user/3 I'll do props settings separately, it's work in progress in a branch on top of this one already. cc @ukutaht * Rename socket assigns * Fixup to 5c9f58e * Fixup * Render ComboBox suggestions asynchronously This commit: - prevents redundant work by checking the socket connection - allows passing no options to the ComboBox component, so that when combined with the `async` option, the options are asynchronously initialized post-render - allows updating the suggestions asynchronously with the `async` option set to `true` - helpful in case of DB queries used for suggestions * Update tests * Throttle comboboxes * Update tests * Dim the search input * Use debounce=200 in ComboBox component * Move creatable option to the top * Ensure there's always a leading slash for goals * Test pageview goals with leading / missing * Make the modal scrollable on small viewports
2023-09-04 14:44:22 +03:00
{:ok, goals} = setup_goals(site)
conn = get(conn, "/#{site.domain}/settings/goals")
resp = html_response(conn, 200)
for g <- goals do
assert element_exists?(
resp,
~s/button[phx-click="delete-goal"][phx-value-goal-id=#{g.id}]#delete-goal-#{g.id}/
)
Edit goals with display names (#4415) * Update Goal schema * Equip ComboBox with the ability of JS selection callbacks * Update factory so display_name is always present * Extend Goals context interface * Update seeds Also farming unsuspecting BEAM programmers for better sample page paths :) * Update ComboBox test * Unify error message color class with helpers seen elsewhere * Use goal.display_name where applicable * Implement LiveView extensions for editing goals * Sprinkle display name in external stats controller tests * Format * Fix goal list mobile view * Update lib/plausible_web/live/goal_settings/list.ex Co-authored-by: Artur Pata <artur.pata@gmail.com> * Update lib/plausible_web/live/goal_settings/form.ex Co-authored-by: Artur Pata <artur.pata@gmail.com> * Update the APIs: plugins and external * Update test so the intent is clearer * Format * Update CHANGELOG * Simplify form tabs tests * Revert "Format" This reverts commit c1647b53071c0423d817de6843733766276b6105. * Fixup format commit that went too far * ComboBox: select the input contents on first focus * Update lib/plausible/goal/schema.ex Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com> * Update lib/plausible/goals/goals.ex Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com> * Update lib/plausible_web/live/goal_settings/form.ex Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com> * Pass form goal instead of just ID * Make tab component dumber * Extract separate render functions for edit and create forms * Update test to account for extracted forms * Inline goal get query * Extract revenue goal settings to a component and avoid computing assigns in flight * Make LV modal preload optional * Disable preload for goal settings form modal * Get rid of phash component ID hack * For another render after render_submit when testing goal updates * Fix LV preload option * Enable preload back for goals modal for now * Make formatter happy * Implement support for preopening of LV modal * Preopen goals modal to avoid feedback gap on loading edited goal * Remove `console.log` call from modal JS * Clean up display name input IDs * Make revenue settings functional on first edit again * Display names: 2nd stage migration * Update migration with data backfill --------- Co-authored-by: Artur Pata <artur.pata@gmail.com> Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
2024-08-09 12:12:00 +03:00
assert element_exists?(
resp,
~s/button[phx-click="edit-goal"][phx-value-goal-id=#{g.id}]#edit-goal-#{g.id}/
)
Improve goal settings UX (#3293) * Add Heroicons dependency * Add name_of/1 html helper Currently with Floki there's no way to query for `[name=foo[some]]` selector * Update changelog * Make goal deletion possible with only goal id * Remove stale goal controllers * Improve ComboBox component - make sure the list options are always of the parent input width - allow passing a suggestion function instead of a module * Stale fixup * Update routes * Use the new goals route in funnel settings * Use a function in the funnel combo * Use function in the props combo * Remove old goals form * Implement new goal settings * Update moduledoc * Fix revenue switch in dark mode * Connect live socket on goal settings page * Fixup * Use Heroicons.trash icon * Tweak goals search input * Remove unused alias * Fix search/button alignment * Fix backspace icon alignment * Delegate :superadmin check to get_for_user/3 I'll do props settings separately, it's work in progress in a branch on top of this one already. cc @ukutaht * Rename socket assigns * Fixup to 5c9f58e * Fixup * Render ComboBox suggestions asynchronously This commit: - prevents redundant work by checking the socket connection - allows passing no options to the ComboBox component, so that when combined with the `async` option, the options are asynchronously initialized post-render - allows updating the suggestions asynchronously with the `async` option set to `true` - helpful in case of DB queries used for suggestions * Update tests * Throttle comboboxes * Update tests * Dim the search input * Use debounce=200 in ComboBox component * Move creatable option to the top * Ensure there's always a leading slash for goals * Test pageview goals with leading / missing * Make the modal scrollable on small viewports
2023-09-04 14:44:22 +03:00
end
end
test "if no goals are present, a proper info is displayed", %{conn: conn, site: site} do
conn = get(conn, "/#{site.domain}/settings/goals")
resp = html_response(conn, 200)
assert resp =~ "No goals configured for this site"
end
test "if goals are present, no info about missing goals is displayed", %{
conn: conn,
site: site
} do
{:ok, _goals} = setup_goals(site)
conn = get(conn, "/#{site.domain}/settings/goals")
resp = html_response(conn, 200)
refute resp =~ "No goals configured for this site"
end
test "add goal button is rendered", %{conn: conn, site: site} do
conn = get(conn, "/#{site.domain}/settings/goals")
resp = html_response(conn, 200)
Edit goals with display names (#4415) * Update Goal schema * Equip ComboBox with the ability of JS selection callbacks * Update factory so display_name is always present * Extend Goals context interface * Update seeds Also farming unsuspecting BEAM programmers for better sample page paths :) * Update ComboBox test * Unify error message color class with helpers seen elsewhere * Use goal.display_name where applicable * Implement LiveView extensions for editing goals * Sprinkle display name in external stats controller tests * Format * Fix goal list mobile view * Update lib/plausible_web/live/goal_settings/list.ex Co-authored-by: Artur Pata <artur.pata@gmail.com> * Update lib/plausible_web/live/goal_settings/form.ex Co-authored-by: Artur Pata <artur.pata@gmail.com> * Update the APIs: plugins and external * Update test so the intent is clearer * Format * Update CHANGELOG * Simplify form tabs tests * Revert "Format" This reverts commit c1647b53071c0423d817de6843733766276b6105. * Fixup format commit that went too far * ComboBox: select the input contents on first focus * Update lib/plausible/goal/schema.ex Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com> * Update lib/plausible/goals/goals.ex Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com> * Update lib/plausible_web/live/goal_settings/form.ex Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com> * Pass form goal instead of just ID * Make tab component dumber * Extract separate render functions for edit and create forms * Update test to account for extracted forms * Inline goal get query * Extract revenue goal settings to a component and avoid computing assigns in flight * Make LV modal preload optional * Disable preload for goal settings form modal * Get rid of phash component ID hack * For another render after render_submit when testing goal updates * Fix LV preload option * Enable preload back for goals modal for now * Make formatter happy * Implement support for preopening of LV modal * Preopen goals modal to avoid feedback gap on loading edited goal * Remove `console.log` call from modal JS * Clean up display name input IDs * Make revenue settings functional on first edit again * Display names: 2nd stage migration * Update migration with data backfill --------- Co-authored-by: Artur Pata <artur.pata@gmail.com> Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
2024-08-09 12:12:00 +03:00
assert element_exists?(resp, ~s/button#add-goal-button[phx-click="add-goal"]/)
Improve goal settings UX (#3293) * Add Heroicons dependency * Add name_of/1 html helper Currently with Floki there's no way to query for `[name=foo[some]]` selector * Update changelog * Make goal deletion possible with only goal id * Remove stale goal controllers * Improve ComboBox component - make sure the list options are always of the parent input width - allow passing a suggestion function instead of a module * Stale fixup * Update routes * Use the new goals route in funnel settings * Use a function in the funnel combo * Use function in the props combo * Remove old goals form * Implement new goal settings * Update moduledoc * Fix revenue switch in dark mode * Connect live socket on goal settings page * Fixup * Use Heroicons.trash icon * Tweak goals search input * Remove unused alias * Fix search/button alignment * Fix backspace icon alignment * Delegate :superadmin check to get_for_user/3 I'll do props settings separately, it's work in progress in a branch on top of this one already. cc @ukutaht * Rename socket assigns * Fixup to 5c9f58e * Fixup * Render ComboBox suggestions asynchronously This commit: - prevents redundant work by checking the socket connection - allows passing no options to the ComboBox component, so that when combined with the `async` option, the options are asynchronously initialized post-render - allows updating the suggestions asynchronously with the `async` option set to `true` - helpful in case of DB queries used for suggestions * Update tests * Throttle comboboxes * Update tests * Dim the search input * Use debounce=200 in ComboBox component * Move creatable option to the top * Ensure there's always a leading slash for goals * Test pageview goals with leading / missing * Make the modal scrollable on small viewports
2023-09-04 14:44:22 +03:00
end
test "search goals input is rendered", %{conn: conn, site: site} do
conn = get(conn, "/#{site.domain}/settings/goals")
resp = html_response(conn, 200)
assert element_exists?(resp, ~s/input[type="text"]#filter-text/)
assert element_exists?(resp, ~s/form[phx-change="filter"]#filter-form/)
end
end
describe "GoalSettings live view" do
setup [:create_user, :log_in, :create_site]
test "allows goal deletion", %{conn: conn, site: site} do
{:ok, [g1, g2 | _]} = setup_goals(site)
{lv, html} = get_liveview(conn, site, with_html?: true)
assert html =~ to_string(g1)
assert html =~ to_string(g2)
html = lv |> element(~s/button#delete-goal-#{g1.id}/) |> render_click()
refute html =~ to_string(g1)
assert html =~ to_string(g2)
html = get(conn, "/#{site.domain}/settings/goals") |> html_response(200)
refute html =~ to_string(g1)
assert html =~ to_string(g2)
end
test "allows list filtering / search", %{conn: conn, site: site} do
{:ok, [g1, g2, g3]} = setup_goals(site)
{lv, html} = get_liveview(conn, site, with_html?: true)
assert html =~ to_string(g1)
assert html =~ to_string(g2)
assert html =~ to_string(g3)
html = type_into_search(lv, to_string(g3))
refute html =~ to_string(g1)
refute html =~ to_string(g2)
assert html =~ to_string(g3)
end
test "allows resetting filter text via backspace icon", %{conn: conn, site: site} do
{:ok, [g1, g2, g3]} = setup_goals(site)
{lv, html} = get_liveview(conn, site, with_html?: true)
refute element_exists?(html, ~s/svg[phx-click="reset-filter-text"]#reset-filter/)
html = type_into_search(lv, to_string(g3))
assert element_exists?(html, ~s/svg[phx-click="reset-filter-text"]#reset-filter/)
html = lv |> element(~s/svg#reset-filter/) |> render_click()
assert html =~ to_string(g1)
assert html =~ to_string(g2)
assert html =~ to_string(g3)
end
test "allows resetting filter text via no match link", %{conn: conn, site: site} do
{:ok, _goals} = setup_goals(site)
lv = get_liveview(conn, site)
html = type_into_search(lv, "Definitely this is not going to render any matches")
assert html =~ "No goals found for this site. Please refine or"
assert html =~ "reset your search"
assert element_exists?(html, ~s/a[phx-click="reset-filter-text"]#reset-filter-hint/)
html = lv |> element(~s/a#reset-filter-hint/) |> render_click()
refute html =~ "No goals found for this site. Please refine or"
end
test "Add Goal form view is rendered immediately, though hidden", %{conn: conn, site: site} do
Improve goal settings UX (#3293) * Add Heroicons dependency * Add name_of/1 html helper Currently with Floki there's no way to query for `[name=foo[some]]` selector * Update changelog * Make goal deletion possible with only goal id * Remove stale goal controllers * Improve ComboBox component - make sure the list options are always of the parent input width - allow passing a suggestion function instead of a module * Stale fixup * Update routes * Use the new goals route in funnel settings * Use a function in the funnel combo * Use function in the props combo * Remove old goals form * Implement new goal settings * Update moduledoc * Fix revenue switch in dark mode * Connect live socket on goal settings page * Fixup * Use Heroicons.trash icon * Tweak goals search input * Remove unused alias * Fix search/button alignment * Fix backspace icon alignment * Delegate :superadmin check to get_for_user/3 I'll do props settings separately, it's work in progress in a branch on top of this one already. cc @ukutaht * Rename socket assigns * Fixup to 5c9f58e * Fixup * Render ComboBox suggestions asynchronously This commit: - prevents redundant work by checking the socket connection - allows passing no options to the ComboBox component, so that when combined with the `async` option, the options are asynchronously initialized post-render - allows updating the suggestions asynchronously with the `async` option set to `true` - helpful in case of DB queries used for suggestions * Update tests * Throttle comboboxes * Update tests * Dim the search input * Use debounce=200 in ComboBox component * Move creatable option to the top * Ensure there's always a leading slash for goals * Test pageview goals with leading / missing * Make the modal scrollable on small viewports
2023-09-04 14:44:22 +03:00
{:ok, _goals} = setup_goals(site)
{_, html} = get_liveview(conn, site, with_html?: true)
Improve goal settings UX (#3293) * Add Heroicons dependency * Add name_of/1 html helper Currently with Floki there's no way to query for `[name=foo[some]]` selector * Update changelog * Make goal deletion possible with only goal id * Remove stale goal controllers * Improve ComboBox component - make sure the list options are always of the parent input width - allow passing a suggestion function instead of a module * Stale fixup * Update routes * Use the new goals route in funnel settings * Use a function in the funnel combo * Use function in the props combo * Remove old goals form * Implement new goal settings * Update moduledoc * Fix revenue switch in dark mode * Connect live socket on goal settings page * Fixup * Use Heroicons.trash icon * Tweak goals search input * Remove unused alias * Fix search/button alignment * Fix backspace icon alignment * Delegate :superadmin check to get_for_user/3 I'll do props settings separately, it's work in progress in a branch on top of this one already. cc @ukutaht * Rename socket assigns * Fixup to 5c9f58e * Fixup * Render ComboBox suggestions asynchronously This commit: - prevents redundant work by checking the socket connection - allows passing no options to the ComboBox component, so that when combined with the `async` option, the options are asynchronously initialized post-render - allows updating the suggestions asynchronously with the `async` option set to `true` - helpful in case of DB queries used for suggestions * Update tests * Throttle comboboxes * Update tests * Dim the search input * Use debounce=200 in ComboBox component * Move creatable option to the top * Ensure there's always a leading slash for goals * Test pageview goals with leading / missing * Make the modal scrollable on small viewports
2023-09-04 14:44:22 +03:00
assert html =~ "Add Goal for #{site.domain}"
Improve goal settings UX (#3293) * Add Heroicons dependency * Add name_of/1 html helper Currently with Floki there's no way to query for `[name=foo[some]]` selector * Update changelog * Make goal deletion possible with only goal id * Remove stale goal controllers * Improve ComboBox component - make sure the list options are always of the parent input width - allow passing a suggestion function instead of a module * Stale fixup * Update routes * Use the new goals route in funnel settings * Use a function in the funnel combo * Use function in the props combo * Remove old goals form * Implement new goal settings * Update moduledoc * Fix revenue switch in dark mode * Connect live socket on goal settings page * Fixup * Use Heroicons.trash icon * Tweak goals search input * Remove unused alias * Fix search/button alignment * Fix backspace icon alignment * Delegate :superadmin check to get_for_user/3 I'll do props settings separately, it's work in progress in a branch on top of this one already. cc @ukutaht * Rename socket assigns * Fixup to 5c9f58e * Fixup * Render ComboBox suggestions asynchronously This commit: - prevents redundant work by checking the socket connection - allows passing no options to the ComboBox component, so that when combined with the `async` option, the options are asynchronously initialized post-render - allows updating the suggestions asynchronously with the `async` option set to `true` - helpful in case of DB queries used for suggestions * Update tests * Throttle comboboxes * Update tests * Dim the search input * Use debounce=200 in ComboBox component * Move creatable option to the top * Ensure there's always a leading slash for goals * Test pageview goals with leading / missing * Make the modal scrollable on small viewports
2023-09-04 14:44:22 +03:00
assert element_exists?(
html,
Implement custom events suggestions (#4092) * Start suggesting event names in goal settings form * Fix tests * Bump phoenix_live_view to 0.20.12 * Implement a criminal hack to track removal of modal's child live components * Revert "Implement a criminal hack to track removal of modal's child live components" This reverts commit f34ceb78f17dbdc531e7be90b7039231cd919c46. * Remove redundant closing brace from currency combo input * Hide batch goal add button when tab selection is in progress * Implement unique modal ID regenerated on every modal close/open cycle * Use unique modal ID as ID suffix to live components in goal settings form * Reset suffix on tab selection to reset live components state on switch * Revert "Bump phoenix_live_view to 0.20.12" This reverts commit 1b1c80198128efe4b9021791c0f279a097fd70f9. * Make unique IDs more predictable * Fix tests for `GoalSettings.Form` * Use unique modal ID in country rule modal * Use unique modal ID in hostname rule modal * Use unique modal ID in page rule form modal * Don't limit detected goals when fetching them for autoconfigure * Escape interpolated Alpine state function argument * Exclude goals with whitespace on either end or consisting only of whitespace * Ensure event name suggestions update after goal deletion * Avoid showing loading spinner when closing modal * Don't enable spinner when new combobox selection is identical * Revert "Don't enable spinner when new combobox selection is identical" This reverts commit a041ba8542432827a48185282aefb4396f69b48f.
2024-06-11 09:28:25 +03:00
~s/#goals-form-modal form[phx-submit="save-goal"]/
Improve goal settings UX (#3293) * Add Heroicons dependency * Add name_of/1 html helper Currently with Floki there's no way to query for `[name=foo[some]]` selector * Update changelog * Make goal deletion possible with only goal id * Remove stale goal controllers * Improve ComboBox component - make sure the list options are always of the parent input width - allow passing a suggestion function instead of a module * Stale fixup * Update routes * Use the new goals route in funnel settings * Use a function in the funnel combo * Use function in the props combo * Remove old goals form * Implement new goal settings * Update moduledoc * Fix revenue switch in dark mode * Connect live socket on goal settings page * Fixup * Use Heroicons.trash icon * Tweak goals search input * Remove unused alias * Fix search/button alignment * Fix backspace icon alignment * Delegate :superadmin check to get_for_user/3 I'll do props settings separately, it's work in progress in a branch on top of this one already. cc @ukutaht * Rename socket assigns * Fixup to 5c9f58e * Fixup * Render ComboBox suggestions asynchronously This commit: - prevents redundant work by checking the socket connection - allows passing no options to the ComboBox component, so that when combined with the `async` option, the options are asynchronously initialized post-render - allows updating the suggestions asynchronously with the `async` option set to `true` - helpful in case of DB queries used for suggestions * Update tests * Throttle comboboxes * Update tests * Dim the search input * Use debounce=200 in ComboBox component * Move creatable option to the top * Ensure there's always a leading slash for goals * Test pageview goals with leading / missing * Make the modal scrollable on small viewports
2023-09-04 14:44:22 +03:00
)
end
test "auto-configuring custom event goals", %{conn: conn, site: site} do
populate_stats(site, [
build(:event, name: "Signup"),
build(:event, name: "Newsletter Signup"),
build(:event, name: "Purchase")
])
autoconfigure_button_selector = ~s/button[phx-click="autoconfigure"]/
assert_suggested_event_name_count = fn html, number ->
assert text_of_element(html, autoconfigure_button_selector) =~
"found #{number} custom events from the last 6 months that are not yet configured as goals"
end
{lv, html} = get_liveview(conn, site, with_html?: true)
# At first, 3 event names are suggested
assert_suggested_event_name_count.(html, 3)
# Add one goal
lv
Implement custom events suggestions (#4092) * Start suggesting event names in goal settings form * Fix tests * Bump phoenix_live_view to 0.20.12 * Implement a criminal hack to track removal of modal's child live components * Revert "Implement a criminal hack to track removal of modal's child live components" This reverts commit f34ceb78f17dbdc531e7be90b7039231cd919c46. * Remove redundant closing brace from currency combo input * Hide batch goal add button when tab selection is in progress * Implement unique modal ID regenerated on every modal close/open cycle * Use unique modal ID as ID suffix to live components in goal settings form * Reset suffix on tab selection to reset live components state on switch * Revert "Bump phoenix_live_view to 0.20.12" This reverts commit 1b1c80198128efe4b9021791c0f279a097fd70f9. * Make unique IDs more predictable * Fix tests for `GoalSettings.Form` * Use unique modal ID in country rule modal * Use unique modal ID in hostname rule modal * Use unique modal ID in page rule form modal * Don't limit detected goals when fetching them for autoconfigure * Escape interpolated Alpine state function argument * Exclude goals with whitespace on either end or consisting only of whitespace * Ensure event name suggestions update after goal deletion * Avoid showing loading spinner when closing modal * Don't enable spinner when new combobox selection is identical * Revert "Don't enable spinner when new combobox selection is identical" This reverts commit a041ba8542432827a48185282aefb4396f69b48f.
2024-06-11 09:28:25 +03:00
|> element("#goals-form-modal form")
|> render_submit(%{goal: %{event_name: "Signup"}})
html = render(lv)
# Now two goals are suggested because one is already added
assert_suggested_event_name_count.(html, 2)
# Delete the goal
goal = Plausible.Repo.get_by(Plausible.Goal, site_id: site.id, event_name: "Signup")
html = lv |> element(~s/button#delete-goal-#{goal.id}/) |> render_click()
# Suggested event name count should be 3 again
assert_suggested_event_name_count.(html, 3)
# Autoconfigure all custom event goals
lv
|> element(autoconfigure_button_selector)
|> render_click()
html = render(lv)
# All possible goals exist - no suggestions anymore
refute html =~ "from the last 6 months"
end
Improve goal settings UX (#3293) * Add Heroicons dependency * Add name_of/1 html helper Currently with Floki there's no way to query for `[name=foo[some]]` selector * Update changelog * Make goal deletion possible with only goal id * Remove stale goal controllers * Improve ComboBox component - make sure the list options are always of the parent input width - allow passing a suggestion function instead of a module * Stale fixup * Update routes * Use the new goals route in funnel settings * Use a function in the funnel combo * Use function in the props combo * Remove old goals form * Implement new goal settings * Update moduledoc * Fix revenue switch in dark mode * Connect live socket on goal settings page * Fixup * Use Heroicons.trash icon * Tweak goals search input * Remove unused alias * Fix search/button alignment * Fix backspace icon alignment * Delegate :superadmin check to get_for_user/3 I'll do props settings separately, it's work in progress in a branch on top of this one already. cc @ukutaht * Rename socket assigns * Fixup to 5c9f58e * Fixup * Render ComboBox suggestions asynchronously This commit: - prevents redundant work by checking the socket connection - allows passing no options to the ComboBox component, so that when combined with the `async` option, the options are asynchronously initialized post-render - allows updating the suggestions asynchronously with the `async` option set to `true` - helpful in case of DB queries used for suggestions * Update tests * Throttle comboboxes * Update tests * Dim the search input * Use debounce=200 in ComboBox component * Move creatable option to the top * Ensure there's always a leading slash for goals * Test pageview goals with leading / missing * Make the modal scrollable on small viewports
2023-09-04 14:44:22 +03:00
end
defp setup_goals(site) do
{:ok, g1} = Plausible.Goals.create(site, %{"page_path" => "/go/to/blog/**"})
{:ok, g2} = Plausible.Goals.create(site, %{"event_name" => "Register"})
Improve goal settings UX (#3293) * Add Heroicons dependency * Add name_of/1 html helper Currently with Floki there's no way to query for `[name=foo[some]]` selector * Update changelog * Make goal deletion possible with only goal id * Remove stale goal controllers * Improve ComboBox component - make sure the list options are always of the parent input width - allow passing a suggestion function instead of a module * Stale fixup * Update routes * Use the new goals route in funnel settings * Use a function in the funnel combo * Use function in the props combo * Remove old goals form * Implement new goal settings * Update moduledoc * Fix revenue switch in dark mode * Connect live socket on goal settings page * Fixup * Use Heroicons.trash icon * Tweak goals search input * Remove unused alias * Fix search/button alignment * Fix backspace icon alignment * Delegate :superadmin check to get_for_user/3 I'll do props settings separately, it's work in progress in a branch on top of this one already. cc @ukutaht * Rename socket assigns * Fixup to 5c9f58e * Fixup * Render ComboBox suggestions asynchronously This commit: - prevents redundant work by checking the socket connection - allows passing no options to the ComboBox component, so that when combined with the `async` option, the options are asynchronously initialized post-render - allows updating the suggestions asynchronously with the `async` option set to `true` - helpful in case of DB queries used for suggestions * Update tests * Throttle comboboxes * Update tests * Dim the search input * Use debounce=200 in ComboBox component * Move creatable option to the top * Ensure there's always a leading slash for goals * Test pageview goals with leading / missing * Make the modal scrollable on small viewports
2023-09-04 14:44:22 +03:00
{:ok, g3} = Plausible.Goals.create(site, %{"event_name" => "Purchase", "currency" => "EUR"})
{:ok, [g1, g2, g3]}
end
defp get_liveview(conn, site, opts \\ []) do
conn = assign(conn, :live_module, PlausibleWeb.Live.GoalSettings)
{:ok, lv, html} = live(conn, "/#{site.domain}/settings/goals")
if Keyword.get(opts, :with_html?) do
{lv, html}
else
lv
end
end
defp type_into_search(lv, text) do
lv
|> element("form#filter-form")
|> render_change(%{
"_target" => ["filter-text"],
"filter-text" => "#{text}"
})
end
end