mirror of
https://github.com/formbricks/formbricks.git
synced 2026-02-27 00:55:40 -06:00
feat: Add auto-refresh to the analysis view (#3007)
Co-authored-by: Matti Nannt <mail@matthiasnannt.com>
This commit is contained in:
@@ -296,7 +296,7 @@ File '/etc/apt/keyrings/docker.gpg' exists. Overwrite? (y/N) y
|
||||
🎉 Hooray! Docker is all set and ready to go. You're now ready to run your Formbricks instance!
|
||||
📁 Created Formbricks Quickstart directory at ./formbricks.
|
||||
🔗 Please enter your domain name for the SSL certificate (🚨 do NOT enter the protocol (http/https/etc)):
|
||||
docs@formbricks.com
|
||||
my.hosted.url.com
|
||||
🔗 Do you want us to set up an HTTPS certificate for you? [Y/n]
|
||||
Y
|
||||
🔗 Please make sure that the domain points to the server's IP address and that ports 80 & 443 are open in your server's firewall. Is everything set up? [Y/n]
|
||||
@@ -326,7 +326,7 @@ Y
|
||||
🔗 To edit more variables and deeper config, go to the formbricks/docker-compose.yml, edit the file, and restart the container!
|
||||
🚨 Make sure you have set up the DNS records as well as inbound rules for the domain name and IP address of this instance.
|
||||
|
||||
🎉 All done! Please setup your Formbricks instance by visiting your domain at https://tls.piyush.formbricks.com. You can check the status of Formbricks & Traefik with 'cd formbricks && sudo docker compose ps.'
|
||||
🎉 All done! Please setup your Formbricks instance by visiting your domain at https://my.hosted.url.com. You can check the status of Formbricks & Traefik with 'cd formbricks && sudo docker compose ps.'
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -1,29 +1,95 @@
|
||||
"use client";
|
||||
|
||||
import { revalidateSurveyIdPath } from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/actions";
|
||||
import { useResponseFilter } from "@/app/(app)/environments/[environmentId]/components/ResponseFilterContext";
|
||||
import {
|
||||
getResponseCountAction,
|
||||
revalidateSurveyIdPath,
|
||||
} from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/actions";
|
||||
import { getFormattedFilters } from "@/app/lib/surveys/surveys";
|
||||
import { getResponseCountBySurveySharingKeyAction } from "@/app/share/[sharingKey]/actions";
|
||||
import { InboxIcon, PresentationIcon } from "lucide-react";
|
||||
import { useParams, usePathname } from "next/navigation";
|
||||
import { useParams, usePathname, useSearchParams } from "next/navigation";
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { TSurvey } from "@formbricks/types/surveys/types";
|
||||
import { SecondaryNavigation } from "@formbricks/ui/SecondaryNavigation";
|
||||
|
||||
interface SurveyAnalysisNavigationProps {
|
||||
environmentId: string;
|
||||
surveyId: string;
|
||||
responseCount: number | null;
|
||||
survey: TSurvey;
|
||||
initialTotalResponseCount: number | null;
|
||||
activeId: string;
|
||||
}
|
||||
|
||||
export const SurveyAnalysisNavigation = ({
|
||||
environmentId,
|
||||
surveyId,
|
||||
responseCount,
|
||||
survey,
|
||||
initialTotalResponseCount,
|
||||
activeId,
|
||||
}: SurveyAnalysisNavigationProps) => {
|
||||
const pathname = usePathname();
|
||||
const params = useParams();
|
||||
const [filteredResponseCount, setFilteredResponseCount] = useState<number | null>(null);
|
||||
const [totalResponseCount, setTotalResponseCount] = useState<number | null>(initialTotalResponseCount);
|
||||
const sharingKey = params.sharingKey as string;
|
||||
const isSharingPage = !!sharingKey;
|
||||
|
||||
const url = isSharingPage ? `/share/${sharingKey}` : `/environments/${environmentId}/surveys/${surveyId}`;
|
||||
const searchParams = useSearchParams();
|
||||
const isShareEmbedModalOpen = searchParams.get("share") === "true";
|
||||
|
||||
const url = isSharingPage ? `/share/${sharingKey}` : `/environments/${environmentId}/surveys/${survey.id}`;
|
||||
const { selectedFilter, dateRange } = useResponseFilter();
|
||||
|
||||
const filters = useMemo(
|
||||
() => getFormattedFilters(survey, selectedFilter, dateRange),
|
||||
[selectedFilter, dateRange]
|
||||
);
|
||||
|
||||
const latestFiltersRef = useRef(filters);
|
||||
latestFiltersRef.current = filters;
|
||||
|
||||
const getResponseCount = () => {
|
||||
if (isSharingPage) return getResponseCountBySurveySharingKeyAction(sharingKey);
|
||||
return getResponseCountAction(survey.id);
|
||||
};
|
||||
|
||||
const fetchResponseCount = async () => {
|
||||
const count = await getResponseCount();
|
||||
setTotalResponseCount(count);
|
||||
};
|
||||
|
||||
const getFilteredResponseCount = () => {
|
||||
if (isSharingPage) return getResponseCountBySurveySharingKeyAction(sharingKey, latestFiltersRef.current);
|
||||
return getResponseCountAction(survey.id, latestFiltersRef.current);
|
||||
};
|
||||
|
||||
const fetchFilteredResponseCount = async () => {
|
||||
const count = await getFilteredResponseCount();
|
||||
setFilteredResponseCount(count);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchFilteredResponseCount();
|
||||
}, [filters, isSharingPage, sharingKey, survey.id]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isShareEmbedModalOpen) {
|
||||
const interval = setInterval(() => {
|
||||
fetchResponseCount();
|
||||
fetchFilteredResponseCount();
|
||||
}, 10000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}
|
||||
}, [isShareEmbedModalOpen]);
|
||||
|
||||
const getResponseCountString = () => {
|
||||
if (totalResponseCount === null) return "";
|
||||
if (filteredResponseCount === null) return `(${totalResponseCount})`;
|
||||
|
||||
if (totalResponseCount === filteredResponseCount) return `(${totalResponseCount})`;
|
||||
|
||||
return `(${filteredResponseCount} of ${totalResponseCount})`;
|
||||
};
|
||||
|
||||
const navigation = [
|
||||
{
|
||||
@@ -33,17 +99,17 @@ export const SurveyAnalysisNavigation = ({
|
||||
href: `${url}/summary?referer=true`,
|
||||
current: pathname?.includes("/summary"),
|
||||
onClick: () => {
|
||||
revalidateSurveyIdPath(environmentId, surveyId);
|
||||
revalidateSurveyIdPath(environmentId, survey.id);
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "responses",
|
||||
label: `Responses ${responseCount !== null ? `(${responseCount})` : ""}`,
|
||||
label: `Responses ${getResponseCountString()}`,
|
||||
icon: <InboxIcon className="h-5 w-5" />,
|
||||
href: `${url}/responses?referer=true`,
|
||||
current: pathname?.includes("/responses"),
|
||||
onClick: () => {
|
||||
revalidateSurveyIdPath(environmentId, surveyId);
|
||||
revalidateSurveyIdPath(environmentId, survey.id);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -157,7 +157,7 @@ export const ResponsePage = ({
|
||||
<>
|
||||
<div className="flex gap-1.5">
|
||||
<CustomFilter survey={survey} />
|
||||
{!isSharingPage && <ResultsShareButton survey={survey} webAppUrl={webAppUrl} user={user} />}
|
||||
{!isSharingPage && <ResultsShareButton survey={survey} webAppUrl={webAppUrl} />}
|
||||
</div>
|
||||
<ResponseTimeline
|
||||
environment={environment}
|
||||
|
||||
@@ -68,9 +68,9 @@ const Page = async ({ params }) => {
|
||||
}>
|
||||
<SurveyAnalysisNavigation
|
||||
environmentId={environment.id}
|
||||
responseCount={totalResponseCount}
|
||||
surveyId={survey.id}
|
||||
survey={survey}
|
||||
activeId="responses"
|
||||
initialTotalResponseCount={totalResponseCount}
|
||||
/>
|
||||
</PageHeader>
|
||||
<ResponsePage
|
||||
|
||||
@@ -5,20 +5,15 @@ import { useEffect, useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import { TEnvironment } from "@formbricks/types/environment";
|
||||
import { TSurvey } from "@formbricks/types/surveys/types";
|
||||
import { TUser } from "@formbricks/types/user";
|
||||
import { Confetti } from "@formbricks/ui/Confetti";
|
||||
import { ShareEmbedSurvey } from "./ShareEmbedSurvey";
|
||||
|
||||
interface SummaryMetadataProps {
|
||||
environment: TEnvironment;
|
||||
survey: TSurvey;
|
||||
webAppUrl: string;
|
||||
user: TUser;
|
||||
}
|
||||
|
||||
export const SuccessMessage = ({ environment, survey, webAppUrl, user }: SummaryMetadataProps) => {
|
||||
export const SuccessMessage = ({ environment, survey }: SummaryMetadataProps) => {
|
||||
const searchParams = useSearchParams();
|
||||
const [showLinkModal, setShowLinkModal] = useState(false);
|
||||
const [confetti, setConfetti] = useState(false);
|
||||
|
||||
const isAppSurvey = survey.type === "app" || survey.type === "website";
|
||||
@@ -39,26 +34,18 @@ export const SuccessMessage = ({ environment, survey, webAppUrl, user }: Summary
|
||||
position: "bottom-right",
|
||||
}
|
||||
);
|
||||
if (survey.type === "link") {
|
||||
setShowLinkModal(true);
|
||||
}
|
||||
|
||||
// Remove success param from url
|
||||
const url = new URL(window.location.href);
|
||||
url.searchParams.delete("success");
|
||||
if (survey.type === "link") {
|
||||
// Add share param to url to open share embed modal
|
||||
url.searchParams.set("share", "true");
|
||||
}
|
||||
|
||||
window.history.replaceState({}, "", url.toString());
|
||||
}
|
||||
}, [environment, isAppSurvey, searchParams, survey, widgetSetupCompleted]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ShareEmbedSurvey
|
||||
survey={survey}
|
||||
open={showLinkModal}
|
||||
setOpen={setShowLinkModal}
|
||||
webAppUrl={webAppUrl}
|
||||
user={user}
|
||||
/>
|
||||
{confetti && <Confetti />}
|
||||
</>
|
||||
);
|
||||
return <>{confetti && <Confetti />}</>;
|
||||
};
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
getSummaryBySurveySharingKeyAction,
|
||||
} from "@/app/share/[sharingKey]/actions";
|
||||
import { useParams, useSearchParams } from "next/navigation";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { replaceHeadlineRecall } from "@formbricks/lib/utils/recall";
|
||||
import { TAttributeClass } from "@formbricks/types/attribute-classes";
|
||||
import { TEnvironment } from "@formbricks/types/environment";
|
||||
@@ -53,7 +53,6 @@ export const SummaryPage = ({
|
||||
survey,
|
||||
surveyId,
|
||||
webAppUrl,
|
||||
user,
|
||||
totalResponseCount,
|
||||
attributeClasses,
|
||||
}: SummaryPageProps) => {
|
||||
@@ -61,6 +60,9 @@ export const SummaryPage = ({
|
||||
const sharingKey = params.sharingKey as string;
|
||||
const isSharingPage = !!sharingKey;
|
||||
|
||||
const searchParams = useSearchParams();
|
||||
const isShareEmbedModalOpen = searchParams.get("share") === "true";
|
||||
|
||||
const [responseCount, setResponseCount] = useState<number | null>(null);
|
||||
const [surveySummary, setSurveySummary] = useState<TSurveySummary>(initialSurveySummary);
|
||||
const [showDropOffs, setShowDropOffs] = useState<boolean>(false);
|
||||
@@ -69,39 +71,48 @@ export const SummaryPage = ({
|
||||
|
||||
const filters = useMemo(
|
||||
() => getFormattedFilters(survey, selectedFilter, dateRange),
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[selectedFilter, dateRange]
|
||||
);
|
||||
|
||||
// Use a ref to keep the latest state and props
|
||||
const latestFiltersRef = useRef(filters);
|
||||
latestFiltersRef.current = filters;
|
||||
|
||||
const getResponseCount = () => {
|
||||
if (isSharingPage) return getResponseCountBySurveySharingKeyAction(sharingKey, latestFiltersRef.current);
|
||||
return getResponseCountAction(surveyId, latestFiltersRef.current);
|
||||
};
|
||||
|
||||
const getSummary = () => {
|
||||
if (isSharingPage) return getSummaryBySurveySharingKeyAction(sharingKey, latestFiltersRef.current);
|
||||
return getSurveySummaryAction(surveyId, latestFiltersRef.current);
|
||||
};
|
||||
|
||||
const handleInitialData = async () => {
|
||||
try {
|
||||
const updatedResponseCount = await getResponseCount();
|
||||
const updatedSurveySummary = await getSummary();
|
||||
|
||||
setResponseCount(updatedResponseCount);
|
||||
setSurveySummary(updatedSurveySummary);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const handleInitialData = async () => {
|
||||
try {
|
||||
let updatedResponseCount;
|
||||
if (isSharingPage) {
|
||||
updatedResponseCount = await getResponseCountBySurveySharingKeyAction(sharingKey, filters);
|
||||
} else {
|
||||
updatedResponseCount = await getResponseCountAction(surveyId, filters);
|
||||
}
|
||||
setResponseCount(updatedResponseCount);
|
||||
|
||||
let updatedSurveySummary;
|
||||
if (isSharingPage) {
|
||||
updatedSurveySummary = await getSummaryBySurveySharingKeyAction(sharingKey, filters);
|
||||
} else {
|
||||
updatedSurveySummary = await getSurveySummaryAction(surveyId, filters);
|
||||
}
|
||||
|
||||
setSurveySummary(updatedSurveySummary);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
|
||||
handleInitialData();
|
||||
}, [filters, isSharingPage, sharingKey, surveyId]);
|
||||
|
||||
const searchParams = useSearchParams();
|
||||
useEffect(() => {
|
||||
if (!isShareEmbedModalOpen) {
|
||||
const interval = setInterval(() => {
|
||||
handleInitialData();
|
||||
}, 10000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}
|
||||
}, [isShareEmbedModalOpen]);
|
||||
|
||||
const surveyMemoized = useMemo(() => {
|
||||
return replaceHeadlineRecall(survey, "default", attributeClasses);
|
||||
@@ -123,7 +134,7 @@ export const SummaryPage = ({
|
||||
{showDropOffs && <SummaryDropOffs dropOff={surveySummary.dropOff} />}
|
||||
<div className="flex gap-1.5">
|
||||
<CustomFilter survey={surveyMemoized} />
|
||||
{!isSharingPage && <ResultsShareButton survey={surveyMemoized} webAppUrl={webAppUrl} user={user} />}
|
||||
{!isSharingPage && <ResultsShareButton survey={surveyMemoized} webAppUrl={webAppUrl} />}
|
||||
</div>
|
||||
<SummaryList
|
||||
summary={surveySummary.summary}
|
||||
|
||||
@@ -4,7 +4,8 @@ import { ShareEmbedSurvey } from "@/app/(app)/environments/[environmentId]/surve
|
||||
import { SuccessMessage } from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/SuccessMessage";
|
||||
import { SurveyStatusDropdown } from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/components/SurveyStatusDropdown";
|
||||
import { ShareIcon, SquarePenIcon } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { usePathname, useRouter, useSearchParams } from "next/navigation";
|
||||
import { useEffect, useState } from "react";
|
||||
import { TEnvironment } from "@formbricks/types/environment";
|
||||
import { TSurvey } from "@formbricks/types/surveys/types";
|
||||
import { TUser } from "@formbricks/types/user";
|
||||
@@ -24,10 +25,36 @@ export const SurveyAnalysisCTA = ({
|
||||
webAppUrl: string;
|
||||
user: TUser;
|
||||
}) => {
|
||||
const [showShareSurveyModal, setShowShareSurveyModal] = useState(false);
|
||||
const searchParams = useSearchParams();
|
||||
const pathname = usePathname();
|
||||
const router = useRouter();
|
||||
|
||||
const [showShareSurveyModal, setShowShareSurveyModal] = useState(searchParams.get("share") === "true");
|
||||
|
||||
const widgetSetupCompleted =
|
||||
survey.type === "app" ? environment.appSetupCompleted : environment.websiteSetupCompleted;
|
||||
|
||||
useEffect(() => {
|
||||
if (searchParams.get("share") === "true") {
|
||||
setShowShareSurveyModal(true);
|
||||
} else {
|
||||
setShowShareSurveyModal(false);
|
||||
}
|
||||
}, [searchParams]);
|
||||
|
||||
const setOpenShareSurveyModal = (open: boolean) => {
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
|
||||
if (open) {
|
||||
searchParams.set("share", "true");
|
||||
setShowShareSurveyModal(true);
|
||||
} else {
|
||||
searchParams.delete("share");
|
||||
setShowShareSurveyModal(false);
|
||||
}
|
||||
|
||||
router.push(`${pathname}?${searchParams.toString()}`);
|
||||
};
|
||||
return (
|
||||
<div className="hidden justify-end gap-x-1.5 sm:flex">
|
||||
{survey.resultShareKey && (
|
||||
@@ -41,7 +68,7 @@ export const SurveyAnalysisCTA = ({
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
setShowShareSurveyModal(true);
|
||||
setOpenShareSurveyModal(true);
|
||||
}}>
|
||||
<ShareIcon className="h-5 w-5" />
|
||||
</Button>
|
||||
@@ -59,13 +86,13 @@ export const SurveyAnalysisCTA = ({
|
||||
<ShareEmbedSurvey
|
||||
survey={survey}
|
||||
open={showShareSurveyModal}
|
||||
setOpen={setShowShareSurveyModal}
|
||||
setOpen={setOpenShareSurveyModal}
|
||||
webAppUrl={webAppUrl}
|
||||
user={user}
|
||||
/>
|
||||
)}
|
||||
|
||||
{user && <SuccessMessage environment={environment} survey={survey} webAppUrl={webAppUrl} user={user} />}
|
||||
{user && <SuccessMessage environment={environment} survey={survey} />}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -76,9 +76,9 @@ const Page = async ({ params }) => {
|
||||
}>
|
||||
<SurveyAnalysisNavigation
|
||||
environmentId={environment.id}
|
||||
responseCount={totalResponseCount}
|
||||
surveyId={survey.id}
|
||||
survey={survey}
|
||||
activeId="summary"
|
||||
initialTotalResponseCount={totalResponseCount}
|
||||
/>
|
||||
</PageHeader>
|
||||
<SummaryPage
|
||||
|
||||
@@ -9,24 +9,20 @@ import { CopyIcon, DownloadIcon, GlobeIcon, LinkIcon } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import { TSurvey } from "@formbricks/types/surveys/types";
|
||||
import { TUser } from "@formbricks/types/user";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@formbricks/ui/DropdownMenu";
|
||||
import { ShareEmbedSurvey } from "../(analysis)/summary/components/ShareEmbedSurvey";
|
||||
import { ShareSurveyResults } from "../(analysis)/summary/components/ShareSurveyResults";
|
||||
|
||||
interface ResultsShareButtonProps {
|
||||
survey: TSurvey;
|
||||
webAppUrl: string;
|
||||
user?: TUser;
|
||||
}
|
||||
|
||||
export const ResultsShareButton = ({ survey, webAppUrl, user }: ResultsShareButtonProps) => {
|
||||
const [showLinkModal, setShowLinkModal] = useState(false);
|
||||
export const ResultsShareButton = ({ survey, webAppUrl }: ResultsShareButtonProps) => {
|
||||
const [showResultsLinkModal, setShowResultsLinkModal] = useState(false);
|
||||
|
||||
const [showPublishModal, setShowPublishModal] = useState(false);
|
||||
@@ -43,7 +39,6 @@ export const ResultsShareButton = ({ survey, webAppUrl, user }: ResultsShareButt
|
||||
.then(() => {
|
||||
toast.success("Results unpublished successfully.");
|
||||
setShowPublishModal(false);
|
||||
setShowLinkModal(false);
|
||||
})
|
||||
.catch((error) => {
|
||||
toast.error(`Error: ${error.message}`);
|
||||
@@ -62,12 +57,6 @@ export const ResultsShareButton = ({ survey, webAppUrl, user }: ResultsShareButt
|
||||
fetchSharingKey();
|
||||
}, [survey.id, webAppUrl]);
|
||||
|
||||
useEffect(() => {
|
||||
if (showResultsLinkModal) {
|
||||
setShowLinkModal(false);
|
||||
}
|
||||
}, [showResultsLinkModal]);
|
||||
|
||||
const copyUrlToClipboard = () => {
|
||||
if (typeof window !== "undefined") {
|
||||
const currentUrl = window.location.href;
|
||||
@@ -134,16 +123,6 @@ export const ResultsShareButton = ({ survey, webAppUrl, user }: ResultsShareButt
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
|
||||
{showLinkModal && user && (
|
||||
<ShareEmbedSurvey
|
||||
survey={survey}
|
||||
open={showLinkModal}
|
||||
setOpen={setShowLinkModal}
|
||||
webAppUrl={webAppUrl}
|
||||
user={user}
|
||||
/>
|
||||
)}
|
||||
{showResultsLinkModal && (
|
||||
<ShareSurveyResults
|
||||
open={showResultsLinkModal}
|
||||
|
||||
@@ -41,10 +41,10 @@ const Page = async ({ params }) => {
|
||||
<PageContentWrapper className="w-full">
|
||||
<PageHeader pageTitle={survey.name}>
|
||||
<SurveyAnalysisNavigation
|
||||
surveyId={survey.id}
|
||||
survey={survey}
|
||||
environmentId={environment.id}
|
||||
activeId="responses"
|
||||
responseCount={totalResponseCount}
|
||||
initialTotalResponseCount={totalResponseCount}
|
||||
/>
|
||||
</PageHeader>
|
||||
<ResponsePage
|
||||
|
||||
@@ -43,10 +43,10 @@ const Page = async ({ params }) => {
|
||||
<PageContentWrapper className="w-full">
|
||||
<PageHeader pageTitle={survey.name}>
|
||||
<SurveyAnalysisNavigation
|
||||
surveyId={survey.id}
|
||||
survey={survey}
|
||||
environmentId={environment.id}
|
||||
activeId="summary"
|
||||
responseCount={totalResponseCount}
|
||||
initialTotalResponseCount={totalResponseCount}
|
||||
/>
|
||||
</PageHeader>
|
||||
<SummaryPage
|
||||
|
||||
@@ -25,7 +25,7 @@ test.describe("Survey Create & Submit Response", async () => {
|
||||
await page.getByRole("button", { name: "Publish" }).click();
|
||||
|
||||
// Get URL
|
||||
await page.waitForURL(/\/environments\/[^/]+\/surveys\/[^/]+\/summary$/);
|
||||
await page.waitForURL(/\/environments\/[^/]+\/surveys\/[^/]+\/summary(\?.*)?$/);
|
||||
await page.getByLabel("Copy survey link to clipboard").click();
|
||||
url = await page.evaluate("navigator.clipboard.readText()");
|
||||
});
|
||||
@@ -435,7 +435,8 @@ test.describe("Multi Language Survey Create", async () => {
|
||||
|
||||
await page.getByRole("button", { name: "Publish" }).click();
|
||||
|
||||
await page.waitForURL(/\/environments\/[^/]+\/surveys\/[^/]+\/summary$/);
|
||||
// await page.waitForURL(/\/environments\/[^/]+\/surveys\/[^/]+\/summary$/);
|
||||
await page.waitForURL(/\/environments\/[^/]+\/surveys\/[^/]+\/summary(\?.*)?$/);
|
||||
await page.getByLabel("Select Language").click();
|
||||
await page.getByText("German").click();
|
||||
await page.getByLabel("Copy survey link to clipboard").click();
|
||||
|
||||
Reference in New Issue
Block a user