Skip to content

Commit af5d124

Browse files
Copilotanupriya13
andcommitted
Add dynamic Button examples and functional tests for fast refresh
Co-authored-by: anupriya13 <54227869+anupriya13@users.noreply.github.com>
1 parent 073bdbd commit af5d124

File tree

2 files changed

+224
-0
lines changed

2 files changed

+224
-0
lines changed

packages/@react-native/tester/js/examples/Button/ButtonExample.js

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,11 +221,146 @@ exports.examples = [
221221
);
222222
},
223223
},
224+
{
225+
title: 'Button with dynamic text',
226+
description: 'Button text updates when pressed',
227+
render: function (): React.Node {
228+
return <DynamicTextButton />;
229+
},
230+
},
231+
{
232+
title: 'Button with dynamic color',
233+
description: 'Button color updates when pressed',
234+
render: function (): React.Node {
235+
return <DynamicColorButton />;
236+
},
237+
},
238+
{
239+
title: 'Button with dynamic disabled state',
240+
description: 'Button disabled state toggles when pressed',
241+
render: function (): React.Node {
242+
return <DynamicDisabledButton />;
243+
},
244+
},
245+
{
246+
title: 'Button with dynamic styling on press',
247+
description: 'Button updates styling when pressed',
248+
render: function (): React.Node {
249+
return <DynamicStyleButton />;
250+
},
251+
},
224252
];
225253

254+
// Dynamic Button Components for fast refresh testing
255+
function DynamicTextButton(): React.Node {
256+
const [buttonText, setButtonText] = React.useState('Initial Text');
257+
const [pressCount, setPressCount] = React.useState(0);
258+
259+
const onPress = () => {
260+
const newCount = pressCount + 1;
261+
setPressCount(newCount);
262+
setButtonText(`Pressed ${newCount} times`);
263+
};
264+
265+
return (
266+
<Button
267+
onPress={onPress}
268+
testID="dynamic_text_button"
269+
title={buttonText}
270+
accessibilityLabel="Press to change button text"
271+
/>
272+
);
273+
}
274+
275+
function DynamicColorButton(): React.Node {
276+
const [colorIndex, setColorIndex] = React.useState(0);
277+
const colors = ['#007AFF', '#FF3B30', '#34C759', '#FF9500', '#5856D6'];
278+
279+
const onPress = () => {
280+
setColorIndex((prev) => (prev + 1) % colors.length);
281+
};
282+
283+
return (
284+
<RNTesterThemeContext.Consumer>
285+
{theme => (
286+
<Button
287+
onPress={onPress}
288+
testID="dynamic_color_button"
289+
color={colors[colorIndex]}
290+
title="Change Color"
291+
accessibilityLabel="Press to change button color"
292+
/>
293+
)}
294+
</RNTesterThemeContext.Consumer>
295+
);
296+
}
297+
298+
function DynamicDisabledButton(): React.Node {
299+
const [isDisabled, setIsDisabled] = React.useState(false);
300+
const [toggleText, setToggleText] = React.useState('Disable Me');
301+
302+
const onPress = () => {
303+
if (!isDisabled) {
304+
setIsDisabled(true);
305+
setToggleText('Disabled');
306+
// Re-enable after 2 seconds for testing
307+
setTimeout(() => {
308+
setIsDisabled(false);
309+
setToggleText('Disable Me');
310+
}, 2000);
311+
}
312+
};
313+
314+
return (
315+
<Button
316+
disabled={isDisabled}
317+
onPress={onPress}
318+
testID="dynamic_disabled_button"
319+
title={toggleText}
320+
accessibilityLabel="Press to toggle disabled state"
321+
/>
322+
);
323+
}
324+
325+
function DynamicStyleButton(): React.Node {
326+
const [isPressed, setIsPressed] = React.useState(false);
327+
const [pressCount, setPressCount] = React.useState(0);
328+
329+
const onPress = () => {
330+
setIsPressed(true);
331+
setPressCount(prev => prev + 1);
332+
// Reset pressed state after visual feedback
333+
setTimeout(() => setIsPressed(false), 300);
334+
};
335+
336+
return (
337+
<RNTesterThemeContext.Consumer>
338+
{theme => (
339+
<View style={[styles.dynamicContainer, isPressed && styles.pressedContainer]}>
340+
<Button
341+
onPress={onPress}
342+
testID="dynamic_style_button"
343+
color={isPressed ? theme.SystemRedColor : theme.LinkColor}
344+
title={`Style Button (${pressCount})`}
345+
accessibilityLabel="Press to update styling"
346+
/>
347+
</View>
348+
)}
349+
</RNTesterThemeContext.Consumer>
350+
);
351+
}
352+
226353
const styles = StyleSheet.create({
227354
container: {
228355
flexDirection: 'row',
229356
justifyContent: 'space-between',
230357
},
358+
dynamicContainer: {
359+
padding: 10,
360+
borderRadius: 5,
361+
backgroundColor: 'transparent',
362+
},
363+
pressedContainer: {
364+
backgroundColor: '#f0f0f0',
365+
},
231366
});

packages/e2e-test-app-fabric/test/ButtonComponentTest.test.ts

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,4 +138,93 @@ describe('Button Tests', () => {
138138
const dump3 = await dumpVisualTree('accessible_focusable_false_button');
139139
expect(dump3).toMatchSnapshot();
140140
});
141+
142+
// Functional tests for dynamic button behaviors
143+
test('Button text should update on fast refresh', async () => {
144+
await searchBox('dynamic text');
145+
const component = await app.findElementByTestID('dynamic_text_button');
146+
await component.waitForDisplayed({timeout: 5000});
147+
148+
// Get initial state
149+
const initialDump = await dumpVisualTree('dynamic_text_button');
150+
expect(initialDump).toMatchSnapshot('initial-text');
151+
152+
// Click to change text
153+
await component.click();
154+
155+
// Verify text updated
156+
const updatedDump = await dumpVisualTree('dynamic_text_button');
157+
expect(updatedDump).toMatchSnapshot('updated-text');
158+
expect(updatedDump.Text).toContain('Pressed 1 times');
159+
});
160+
161+
test('Button color should update on fast refresh', async () => {
162+
await searchBox('dynamic color');
163+
const component = await app.findElementByTestID('dynamic_color_button');
164+
await component.waitForDisplayed({timeout: 5000});
165+
166+
// Get initial state
167+
const initialDump = await dumpVisualTree('dynamic_color_button');
168+
expect(initialDump).toMatchSnapshot('initial-color');
169+
170+
// Click to change color
171+
await component.click();
172+
173+
// Verify color updated (visual tree should show different styling)
174+
const updatedDump = await dumpVisualTree('dynamic_color_button');
175+
expect(updatedDump).toMatchSnapshot('updated-color');
176+
});
177+
178+
test('Button disabled status should update on fast refresh', async () => {
179+
await searchBox('dynamic disabled');
180+
const component = await app.findElementByTestID('dynamic_disabled_button');
181+
await component.waitForDisplayed({timeout: 5000});
182+
183+
// Get initial state (should be enabled)
184+
const initialDump = await dumpVisualTree('dynamic_disabled_button');
185+
expect(initialDump).toMatchSnapshot('initial-enabled');
186+
187+
// Click to disable
188+
await component.click();
189+
190+
// Verify button is now disabled
191+
const disabledDump = await dumpVisualTree('dynamic_disabled_button');
192+
expect(disabledDump).toMatchSnapshot('disabled-state');
193+
expect(disabledDump.Text).toContain('Disabled');
194+
195+
// Wait for auto re-enable (2 seconds)
196+
await app.waitUntil(
197+
async () => {
198+
const dump = await dumpVisualTree('dynamic_disabled_button');
199+
return dump.Text.includes('Disable Me');
200+
},
201+
{
202+
timeout: 3000,
203+
interval: 500,
204+
timeoutMsg: 'Button should auto re-enable after 2 seconds',
205+
}
206+
);
207+
208+
// Verify button is enabled again
209+
const reEnabledDump = await dumpVisualTree('dynamic_disabled_button');
210+
expect(reEnabledDump).toMatchSnapshot('re-enabled-state');
211+
});
212+
213+
test('Button should update relevant styling upon press', async () => {
214+
await searchBox('dynamic styling');
215+
const component = await app.findElementByTestID('dynamic_style_button');
216+
await component.waitForDisplayed({timeout: 5000});
217+
218+
// Get initial state
219+
const initialDump = await dumpVisualTree('dynamic_style_button');
220+
expect(initialDump).toMatchSnapshot('initial-styling');
221+
222+
// Click to change styling
223+
await component.click();
224+
225+
// Verify styling updated (should show press count and temporary color change)
226+
const updatedDump = await dumpVisualTree('dynamic_style_button');
227+
expect(updatedDump).toMatchSnapshot('updated-styling');
228+
expect(updatedDump.Text).toContain('Style Button (1)');
229+
});
141230
});

0 commit comments

Comments
 (0)