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
request: different screen size #37
Comments
Hey @Lyokone, I have written a
import 'package:alchemist/alchemist.dart';
import 'package:flutter/material.dart';
import 'device.dart';
/// Wrapper for testing widgets (primarily screens) with device constraints
class GoldenTestDeviceScenario extends StatelessWidget {
final String name;
final Device device;
final ValueGetter<Widget> builder;
const GoldenTestDeviceScenario({
required this.name,
required this.builder,
this.device = Device.iphone11,
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return GoldenTestScenario(
name: '${this.name} (device: ${device.name})',
child: ClipRect(
child: MediaQuery(
data: MediaQuery.of(context).copyWith(
size: this.device.size,
padding: this.device.safeArea,
platformBrightness: this.device.brightness,
devicePixelRatio: this.device.devicePixelRatio,
textScaleFactor: this.device.textScaleFactor,
),
child: SizedBox(
height: this.device.size.height,
width: this.device.size.width,
child: builder(),
),
),
),
);
}
}
// Copied and adapted from https://github.com/eBay/flutter_glove_box/blob/master/packages/golden_toolkit/lib/src/device.dart
import 'package:flutter/material.dart';
/// This [Device] is a configuration for golden test.
class Device {
/// This [Device] is a configuration for golden test.
const Device({
required this.size,
required this.name,
this.devicePixelRatio = 1.0,
this.textScaleFactor = 1.0,
this.brightness = Brightness.light,
this.safeArea = const EdgeInsets.all(0),
});
/// [smallPhone] one of the smallest phone screens
static const Device smallPhone =
Device(name: 'small_phone', size: Size(375, 667));
/// [iphone11] matches specs of iphone11, but with lower DPI for performance
static const Device iphone11 = Device(
name: 'iphone11',
size: Size(414, 896),
devicePixelRatio: 1.0,
safeArea: EdgeInsets.only(top: 44, bottom: 34),
);
static const Device iphone11Landscape = Device(
name: 'iphone11_landscape',
size: Size(896, 414),
devicePixelRatio: 1.0,
safeArea: EdgeInsets.only(left: 44, right: 34),
);
/// [tabletLandscape] example of tablet that in landscape mode
static const Device tabletLandscape =
Device(name: 'tablet_landscape', size: Size(1366, 1024));
/// [tabletPortrait] example of tablet that in portrait mode
static const Device tabletPortrait =
Device(name: 'tablet_portrait', size: Size(1024, 1366));
/// [name] specify device name. Ex: Phone, Tablet, Watch
final String name;
/// [size] specify device screen size. Ex: Size(1366, 1024))
final Size size;
/// [devicePixelRatio] specify device Pixel Ratio
final double devicePixelRatio;
/// [textScaleFactor] specify custom text scale factor
final double textScaleFactor;
/// [brightness] specify platform brightness
final Brightness brightness;
/// [safeArea] specify insets to define a safe area
final EdgeInsets safeArea;
/// [copyWith] convenience function for [Device] modification
Device copyWith({
Size? size,
double? devicePixelRatio,
String? name,
double? textScale,
Brightness? brightness,
EdgeInsets? safeArea,
}) {
return Device(
size: size ?? this.size,
devicePixelRatio: devicePixelRatio ?? this.devicePixelRatio,
name: name ?? this.name,
textScaleFactor: textScale ?? this.textScaleFactor,
brightness: brightness ?? this.brightness,
safeArea: safeArea ?? this.safeArea,
);
}
/// [dark] convenience method to copy the current device and apply dark theme
Device dark() {
return Device(
size: size,
devicePixelRatio: devicePixelRatio,
textScaleFactor: textScaleFactor,
brightness: Brightness.dark,
safeArea: safeArea,
name: '${name}_dark',
);
}
@override
String toString() {
return 'Device: $name, '
'${size.width}x${size.height} @ $devicePixelRatio, '
'text: $textScaleFactor, $brightness, safe: $safeArea';
}
} And in the test which you want to run with different device configurations: import 'package:alchemist/alchemist.dart';
import 'package:flutter/material.dart';
import 'device.dart';
import 'golden_test_device_scenario.dart';
void main() {
Widget buildWidgetUnderTest() => MaterialApp(
home: Scaffold(
body: ListView.builder(
itemBuilder: (context, i) => Text('$i'),
),
),
);
goldenTest(
'golden test',
fileName: 'foo_widget',
builder: () => GoldenTestGroup(
children: [
GoldenTestDeviceScenario(
device: Device.smallPhone,
name: 'golden test FooWidget on small phone',
builder: buildWidgetUnderTest,
),
GoldenTestDeviceScenario(
device: Device.tabletLandscape,
name: 'golden test FooWidget on tablet',
builder: buildWidgetUnderTest,
),
],
),
);
} This test will generate the following golden image An important thing to note is that you will run into trouble if your image ends up being larger than 2000 x 2000 pixels (e.g. if you run a lot of golden test scenarios with large devices in one @definitelyokay @Kirpal I can create a PR containing this code if you think it makes sense. |
Wow! Such an insightful response!! Thanks a lot 😍 |
@Giuspepe that's pretty cool! A pull request would definitely be appreciated. Do you think it's worth revisiting the resizing/constraints logic at the same time to avoid using hacky |
A PR is currently in the pipeline related to this functionality, #59. @Giuspepe @Kirpal @Lyokone, Seeing as we can define scenario-specific constraints once that PR has merged, and you can already use custom widgets as @Giuspepe has shown, can we considered this issue fixed? 👀 If not, feel free to comment and let us know if there's anything you'd like us to have a look at! |
Hello, looks like everything needed is here 😁 |
@Giuspepe you are awesome thank you for sharing this. |
Is there an existing feature request for this?
Command
I would love if I could run my tests with a lot of screen sizes (iPhone / iPad / desktop)
Description
I would love if I could generate file the same way golden toolkit is doing
Reasoning
Since variant is used for the platform, I cannot find a way to keep the device type properly organized with Alchemist.
Variants are useful to get also a nice overview in IDEs.
Additional context and comments
No response
The text was updated successfully, but these errors were encountered: