diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.test.tsx b/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.test.tsx
new file mode 100644
index 0000000000..2b091883ae
--- /dev/null
+++ b/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.test.tsx
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2022 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React from 'react';
+import { TemplateParameterSchema } from '../../../types';
+import { Stepper } from './Stepper';
+import { renderInTestApp } from '@backstage/test-utils';
+import { fireEvent } from '@testing-library/react';
+
+describe('Stepper', () => {
+ it('should render the step titles for each step of the manifest', async () => {
+ const manifest: TemplateParameterSchema = {
+ steps: [
+ { title: 'Step 1', schema: { properties: {} } },
+ { title: 'Step 2', schema: { properties: {} } },
+ ],
+ title: 'React JSON Schema Form Test',
+ };
+
+ const { getByText } = await renderInTestApp(
+ ,
+ );
+
+ for (const step of manifest.steps) {
+ expect(getByText(step.title)).toBeInTheDocument();
+ }
+ });
+
+ it('should render next / review button', async () => {
+ const manifest: TemplateParameterSchema = {
+ steps: [
+ { title: 'Step 1', schema: { properties: {} } },
+ { title: 'Step 2', schema: { properties: {} } },
+ ],
+ title: 'React JSON Schema Form Test',
+ };
+
+ const { getByText } = await renderInTestApp(
+ ,
+ );
+
+ expect(getByText('Next')).toBeInTheDocument();
+
+ await fireEvent.click(getByText('Next'));
+
+ expect(getByText('Review')).toBeInTheDocument();
+ });
+
+ it('should remember the state of the form when cycling through the pages', async () => {
+ const manifest: TemplateParameterSchema = {
+ steps: [
+ {
+ title: 'Step 1',
+ schema: {
+ properties: {
+ name: {
+ type: 'string',
+ },
+ },
+ },
+ },
+ {
+ title: 'Step 2',
+ schema: {
+ properties: {
+ description: {
+ type: 'string',
+ },
+ },
+ },
+ },
+ ],
+ title: 'React JSON Schema Form Test',
+ };
+
+ const { getByRole, getByText } = await renderInTestApp(
+ ,
+ );
+
+ await fireEvent.change(getByRole('textbox', { name: 'name' }), {
+ target: { value: 'im a test value' },
+ });
+
+ await fireEvent.click(getByText('Next'));
+
+ await fireEvent.click(getByText('Back'));
+
+ expect(getByRole('textbox', { name: 'name' })).toHaveValue(
+ 'im a test value',
+ );
+ });
+
+ it('should render custom field extensions properly', async () => {
+ const MockComponent = () => {
+ return
im a custom field extension
;
+ };
+
+ const manifest: TemplateParameterSchema = {
+ title: 'Custom Fields',
+ steps: [
+ {
+ title: 'Test',
+ schema: {
+ properties: {
+ name: {
+ type: 'string',
+ 'ui:field': 'Mock',
+ },
+ },
+ },
+ },
+ ],
+ };
+
+ const { getByText } = await renderInTestApp(
+ ,
+ );
+
+ expect(getByText('im a custom field extension')).toBeInTheDocument();
+ });
+});
diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx b/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx
index f864e9ee09..19335d4993 100644
--- a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx
+++ b/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/Stepper.tsx
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+import { JsonObject } from '@backstage/types';
import {
Stepper as MuiStepper,
Step as MuiStep,
@@ -51,6 +52,7 @@ const Form = withTheme(MuiTheme);
export const Stepper = (props: StepperProps) => {
const { steps } = useTemplateSchema(props.manifest);
const [activeStep, setActiveStep] = useState(0);
+ const [formState, setFormState] = useState({});
const styles = useStyles();
const extensions = useMemo(() => {
@@ -62,8 +64,10 @@ export const Stepper = (props: StepperProps) => {
const handleBack = () => {
setActiveStep(prevActiveStep => prevActiveStep - 1);
};
- const handleNext = () => {
+
+ const handleNext = ({ formData }: { formData: JsonObject }) => {
setActiveStep(prevActiveStep => prevActiveStep + 1);
+ setFormState(current => ({ ...current, ...formData }));
};
return (
@@ -77,6 +81,7 @@ export const Stepper = (props: StepperProps) => {