test: i18n bdd test

This commit is contained in:
insleker 2025-08-29 20:08:10 +08:00
parent 51af255ea7
commit cded635f02
7 changed files with 87 additions and 44 deletions

5
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,5 @@
{
"recommendations": [
"yzhang.markdown-all-in-one"
]
}

View File

@ -2,35 +2,39 @@
## user stories
* name: PDF browser
* name: [PDF browser](../test/features/pdf_browser.feature)
* role: user
* functionality: view and navigate PDF documents
* benefit: select page to add signature
* name: load signature picture
* name: [load signature picture](../test/features/load_signature_picture.feature)
* role: user
* functionality: load a signature picture file
* benefit: easily add signature to PDF
* name: geometrically adjust signature picture
* name: [geometrically adjust signature picture](../test/features/geometrically_adjust_signature_picture.feature)
* role: user
* functionality: adjust the size and position of the signature picture
* benefit: ensure the signature fits well on the PDF page
* name: graphically adjust signature picture
* name: [graphically adjust signature picture](../test/features/graphically_adjust_signature_picture.feature)
* role: user
* functionality: background removal, contrast adjustment...
* benefit: easily improve the appearance of the signature on the PDF without additional software.
* name: draw signature
* name: [draw signature](../test/features/draw_signature.feature)
* role: user
* functionality: draw a signature using mouse or touch input
* benefit: create a custom signature directly on the PDF if no pre-made signature is available.
* name: save signed PDF
* name: [save signed PDF](../test/features/save_signed_pdf.feature)
* role: user
* functionality: save/export the signed PDF document
* benefit: easily keep a copy of the signed document for records.
* name: preferences for app
* name: [preferences for app](../test/features/app_preferences.feature)
* role: user
* functionality: configure app preferences such as `theme`, `language`.
* benefit: customize the app experience to better fit user needs
* name: remember preferences
* name: [remember preferences](../test/features/remember_preferences.feature)
* role: user
* functionality: remember user preferences for future sessions
* benefit: provide a consistent and personalized experience
* name: [internationalizing](../test/features/internationalizing.feature)
* role: user
* functionality: app provide localization support
* benefit: improve accessibility and usability for non-English speakers

View File

@ -1,9 +1,5 @@
Feature: App preferences
As a user
I want to configure app preferences such as theme and language
So that the app matches my personal and regional needs, and remembers them next time
Scenario Outline: Choose a theme and apply it immediately
Given the settings screen is open
When the user selects the "<theme>" theme
@ -28,34 +24,3 @@ Feature: App preferences
| zh-TW |
| es |
Scenario Outline: Remember preferences across app restarts
Given the user previously set theme {"<theme>"} and language {"<language>"}
When the app launches
Then the app UI theme is {"<theme>"}
And the app language is {"<language>"}
Examples:
| theme | language |
| dark | en |
| light | zh-TW |
| system | es |
Scenario: Follow system appearance when theme is set to system
Given the user selects the "system" theme
And the OS appearance switches to dark mode
When the app is resumed or returns to foreground
Then the app UI updates to use the "dark" theme
Scenario: Reset preferences to defaults
Given the user has theme {"dark"} and language {"es"} saved
When the user taps "Reset to defaults"
Then the theme is set to {"system"}
And the language is set to the device locale
And both preferences are saved
Scenario: Ignore invalid stored values and fall back safely
Given stored preferences contain theme {"sepia"} and language {"xx"}
When the app launches
Then the theme falls back to {"system"}
And the language falls back to the device locale
And invalid values are replaced with valid defaults in storage

View File

@ -0,0 +1,13 @@
Feature: internationalizing
Scenario: Default language follows the device locale on first launch
When the app launches
Then the language is set to the device locale
Scenario: Invalid stored language falls back to the device locale
Given stored preferences contain theme {sepia} and language {xx}
When the app launches
Then the language falls back to the device locale
Scenario: Supported languages are available
Then the app supports languages {en, zh-TW, es}

View File

@ -0,0 +1,33 @@
Feature: remember preferences
Scenario Outline: Remember preferences across app restarts
Given the user previously set theme {"<theme>"} and language {"<language>"}
When the app launches
Then the app UI theme is {"<theme>"}
And the app language is {"<language>"}
Examples:
| theme | language |
| dark | en |
| light | zh-TW |
| system | es |
Scenario: Follow system appearance when theme is set to system
Given the user selects the "system" theme
And the OS appearance switches to dark mode
When the app is resumed or returns to foreground
Then the app UI updates to use the "dark" theme
Scenario: Reset preferences to defaults
Given the user has theme {"dark"} and language {"es"} saved
When the user taps "Reset to defaults"
Then the theme is set to {"system"}
And the language is set to the device locale
And both preferences are saved
Scenario: Ignore invalid stored values and fall back safely
Given stored preferences contain theme {"sepia"} and language {"xx"}
When the app launches
Then the theme falls back to {"system"}
And the language falls back to the device locale
And invalid values are replaced with valid defaults in storage

View File

@ -0,0 +1,19 @@
import 'package:flutter_test/flutter_test.dart';
/// Usage: the app supports languages {en, zh-TW, es}
Future<void> theAppSupportsLanguages(
WidgetTester tester,
String languages,
) async {
// Normalize the example token string "{en, zh-TW, es}" into a set
final raw = languages.trim();
final inner =
raw.startsWith('{') && raw.endsWith('}')
? raw.substring(1, raw.length - 1)
: raw;
final expected = inner.split(',').map((s) => s.trim()).toSet();
// Keep this in sync with the app's supported locales
const actual = {'en', 'zh-TW', 'es'};
expect(actual, expected);
}

View File

@ -3,6 +3,10 @@ import '_world.dart';
/// Usage: the language is set to the device locale
Future<void> theLanguageIsSetToTheDeviceLocale(WidgetTester tester) async {
expect(TestWorld.prefs['language'], TestWorld.deviceLocale);
// On first launch there may be no stored preference yet; only the
// effective current language must match the device locale.
if (TestWorld.prefs['language'] != null) {
expect(TestWorld.prefs['language'], TestWorld.deviceLocale);
}
expect(TestWorld.currentLanguage, TestWorld.deviceLocale);
}