blob: 46cf171fb3f9cdce8a8d202e4c29fba5a8865682 [file] [log] [blame] [edit]
/*
* Copyright (C) 2023-2024 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if !__has_feature(objc_arc)
#error This file requires ARC. Add the "-fobjc-arc" compiler flag for this file.
#endif
#import "config.h"
#if ENABLE(WK_WEB_EXTENSIONS)
#import "CocoaHelpers.h"
#import "HTTPServer.h"
#import "WebExtensionUtilities.h"
@interface NSLocale ()
+ (NSString *)_deviceLanguage;
@end
static NSString * const messageKey = @"message";
static NSString * const placeholdersKey = @"placeholders";
static NSString * const placeholderDictionaryContentKey = @"content";
static NSLocale *currentLocale = NSLocale.currentLocale;
static NSWritingDirection writingDirection = [NSParagraphStyle defaultWritingDirectionForLanguage:currentLocale.languageCode];
static NSString *textDirection = writingDirection == NSWritingDirectionLeftToRight ? @"ltr" : @"rtl";
static NSString *reversedTextDirection = writingDirection == NSWritingDirectionLeftToRight ? @"rtl" : @"ltr";
static NSString *startEdge = writingDirection == NSWritingDirectionLeftToRight ? @"left" : @"right";
static NSString *endEdge = writingDirection == NSWritingDirectionLeftToRight ? @"right" : @"left";
namespace TestWebKitAPI {
static auto *localizationManifest = @{
@"manifest_version": @3,
@"name": @"Localization Test",
@"description": @"Localization Test",
@"version": @"1",
@"background": @{
@"scripts": @[ @"background.js" ],
@"type": @"module",
@"persistent": @NO,
},
@"default_locale": @"en"
};
static auto *messages = @{
@"extension_name": @{
@"message": @"Web Extension Test Extension",
@"description": @"The display name for the extension."
},
@"extension_description": @{
@"message": @"This is a Web Extension. Tell us what your extension does here",
@"description": @"Description of what the extension does."
}
};
static NSString *localeStringInWebExtensionFormat(NSLocale *locale)
{
if (!locale.languageCode.length)
return @"und";
if (locale.countryCode.length)
return [NSString stringWithFormat:@"%@-%@", locale.languageCode, locale.countryCode];
return locale.languageCode;
}
static NSString *currentLocaleString = localeStringInWebExtensionFormat(currentLocale);
static NSString *currentSystemLocaleString = NSLocale._deviceLanguage;
static auto *baseURLString = @"test-extension://76C788B8-3374-400D-8259-40E5B9DF79D3";
TEST(WKWebExtensionAPILocalization, Errors)
{
auto *backgroundScript = Util::constructScript(@[
@"browser.test.assertThrows(() => browser.i18n.getMessage(''), /'name' value is invalid, because it cannot be empty/i)",
@"browser.test.assertThrows(() => browser.i18n.getMessage(), /a required argument is missing/i)",
@"browser.test.assertThrows(() => browser.i18n.getMessage(123), /'name' value is invalid, because a string is expected/i)",
@"browser.test.assertThrows(() => browser.i18n.getMessage(null), /'name' value is invalid, because a string is expected/i)",
@"browser.test.assertThrows(() => browser.i18n.getMessage(undefined), /'name' value is invalid, because a string is expected/i)",
// Finish
@"browser.test.notifyPass()",
]);
auto manager = Util::parseExtension(localizationManifest, @{ @"background.js": backgroundScript, @"_locales/en/messages.json": messages });
// Set a base URL so it is a known value and not the default random one.
[WKWebExtensionMatchPattern registerCustomURLScheme:@"test-extension"];
manager.get().context.baseURL = [NSURL URLWithString:baseURLString];
[manager loadAndRun];
}
TEST(WKWebExtensionAPILocalization, i18n)
{
NSArray<NSString *> *preferredLocaleIdentifiers = NSLocale.preferredLanguages;
NSMutableOrderedSet<NSString *> *acceptedLanguages = [NSMutableOrderedSet orderedSetWithCapacity:preferredLocaleIdentifiers.count];
for (NSString *localeIdentifier in preferredLocaleIdentifiers) {
[acceptedLanguages addObject:localeIdentifier];
[acceptedLanguages addObject:[NSLocale localeWithLocaleIdentifier:localeIdentifier].languageCode];
}
auto *acceptedLanguagesString = Util::constructJSArrayOfStrings(acceptedLanguages.array);
auto *preferredLanguagesString = Util::constructJSArrayOfStrings(preferredLocaleIdentifiers);
auto *backgroundScript = Util::constructScript(@[
[NSString stringWithFormat:@"const acceptedLanguages = %@", acceptedLanguagesString],
[NSString stringWithFormat:@"const preferredLanguages = %@", preferredLanguagesString],
[NSString stringWithFormat:@"const currentUILanguage = '%@'", currentLocaleString],
[NSString stringWithFormat:@"const currentSystemUILanguage = '%@'", currentSystemLocaleString],
[NSString stringWithFormat:@"const textDirection = '%@'", textDirection],
[NSString stringWithFormat:@"const reversedTextDirection = '%@'", reversedTextDirection],
[NSString stringWithFormat:@"const startEdge = '%@'", startEdge],
[NSString stringWithFormat:@"const endEdge = '%@'", endEdge],
@"browser.test.assertEq(browser.i18n.getMessage('extension_name'), 'Web Extension Test Extension')",
@"browser.test.assertEq(browser.i18n.getMessage('@@extension_id'), '76C788B8-3374-400D-8259-40E5B9DF79D3')",
@"browser.test.assertEq(browser.i18n.getMessage('@@ui_locale'), 'en')",
@"browser.test.assertEq(browser.i18n.getMessage('@@bidi_dir'), textDirection)",
@"browser.test.assertEq(browser.i18n.getMessage('@@bidi_reversed_dir'), reversedTextDirection)",
@"browser.test.assertEq(browser.i18n.getMessage('@@bidi_start_edge'), startEdge)",
@"browser.test.assertEq(browser.i18n.getMessage('@@bidi_end_edge'), endEdge)",
@"browser.test.assertEq(browser.i18n.getMessage('unknown_message'), '')",
@"browser.test.assertFalse(currentUILanguage === 'und')",
@"browser.test.assertEq(browser.i18n.getUILanguage(), currentUILanguage)",
@"browser.test.assertDeepEq(await browser.i18n.getAcceptLanguages(), acceptedLanguages)",
@"browser.test.assertFalse(currentSystemUILanguage === 'und')",
@"browser.test.assertEq(await browser.i18n.getSystemUILanguage(), currentSystemUILanguage)",
@"browser.test.assertDeepEq(await browser.i18n.getPreferredSystemLanguages(), preferredLanguages)",
@"browser.test.notifyPass()",
]);
auto manager = Util::parseExtension(localizationManifest, @{ @"background.js": backgroundScript, @"_locales/en/messages.json": messages });
// Set a base URL so it is a known value and not the default random one.
[WKWebExtensionMatchPattern registerCustomURLScheme:@"test-extension"];
manager.get().context.baseURL = [NSURL URLWithString:baseURLString];
[manager loadAndRun];
}
TEST(WKWebExtensionAPILocalization, i18nWithFallback)
{
// Temporarily set the current locale to US English for the test.
[NSUserDefaults.standardUserDefaults setVolatileDomain:@{ @"AppleLanguages": @[ @"en-US" ] } forName:NSArgumentDomain];
NSArray<NSString *> *preferredLocaleIdentifiers = NSLocale.preferredLanguages;
NSMutableOrderedSet<NSString *> *acceptedLanguages = [NSMutableOrderedSet orderedSetWithCapacity:preferredLocaleIdentifiers.count];
for (NSString *localeIdentifier in preferredLocaleIdentifiers) {
[acceptedLanguages addObject:localeIdentifier];
[acceptedLanguages addObject:[NSLocale localeWithLocaleIdentifier:localeIdentifier].languageCode];
}
auto *acceptedLanguagesString = Util::constructJSArrayOfStrings(acceptedLanguages.array);
auto *preferredLanguagesString = Util::constructJSArrayOfStrings(preferredLocaleIdentifiers);
auto *backgroundScript = Util::constructScript(@[
[NSString stringWithFormat:@"const acceptedLanguages = %@", acceptedLanguagesString],
[NSString stringWithFormat:@"const preferredLanguages = %@", preferredLanguagesString],
[NSString stringWithFormat:@"const currentUILanguage = '%@'", currentLocaleString],
[NSString stringWithFormat:@"const currentSystemUILanguage = '%@'", currentSystemLocaleString],
[NSString stringWithFormat:@"const textDirection = '%@'", textDirection],
[NSString stringWithFormat:@"const reversedTextDirection = '%@'", reversedTextDirection],
[NSString stringWithFormat:@"const startEdge = '%@'", startEdge],
[NSString stringWithFormat:@"const endEdge = '%@'", endEdge],
@"browser.test.assertEq(browser.i18n.getMessage('extension_name'), 'Web Extension Test Extension')",
@"browser.test.assertEq(browser.i18n.getMessage('default_name'), 'Default String')",
@"browser.test.assertEq(browser.i18n.getMessage('regional_name'), 'Regional String')",
@"browser.test.assertEq(browser.i18n.getMessage('@@extension_id'), '76C788B8-3374-400D-8259-40E5B9DF79D3')",
@"browser.test.assertEq(browser.i18n.getMessage('@@ui_locale'), 'en_US')",
@"browser.test.assertEq(browser.i18n.getMessage('@@bidi_dir'), textDirection)",
@"browser.test.assertEq(browser.i18n.getMessage('@@bidi_reversed_dir'), reversedTextDirection)",
@"browser.test.assertEq(browser.i18n.getMessage('@@bidi_start_edge'), startEdge)",
@"browser.test.assertEq(browser.i18n.getMessage('@@bidi_end_edge'), endEdge)",
@"browser.test.assertEq(browser.i18n.getMessage('unknown_message'), '')",
@"browser.test.assertFalse(currentUILanguage === 'und')",
@"browser.test.assertEq(browser.i18n.getUILanguage(), currentUILanguage)",
@"browser.test.assertDeepEq(await browser.i18n.getAcceptLanguages(), acceptedLanguages)",
@"browser.test.assertFalse(currentSystemUILanguage === 'und')",
@"browser.test.assertEq(await browser.i18n.getSystemUILanguage(), currentSystemUILanguage)",
@"browser.test.assertDeepEq(await browser.i18n.getPreferredSystemLanguages(), preferredLanguages)",
@"browser.test.notifyPass()",
]);
auto *manifest = @{
@"manifest_version": @3,
@"name": @"Localization Test",
@"description": @"Localization Test",
@"version": @"1",
@"background": @{
@"scripts": @[ @"background.js" ],
@"type": @"module",
@"persistent": @NO,
},
@"default_locale": @"fr"
};
auto *defaultMessages = @{
@"default_name": @{
@"message": @"Default String",
@"description": @"The test name."
}
};
auto *regionalMessages = @{
@"regional_name": @{
@"message": @"Regional String",
@"description": @"The regional name."
}
};
auto *resources = @{
@"background.js": backgroundScript,
@"_locales/fr/messages.json": defaultMessages,
@"_locales/en/messages.json": messages,
@"_locales/en_US/messages.json": regionalMessages,
};
auto manager = Util::parseExtension(manifest, resources);
// Set a base URL so it is a known value and not the default random one.
[WKWebExtensionMatchPattern registerCustomURLScheme:@"test-extension"];
manager.get().context.baseURL = [NSURL URLWithString:baseURLString];
[manager loadAndRun];
}
TEST(WKWebExtensionAPILocalization, i18nWithoutMessages)
{
NSArray<NSString *> *preferredLocaleIdentifiers = NSLocale.preferredLanguages;
NSMutableOrderedSet<NSString *> *acceptedLanguages = [NSMutableOrderedSet orderedSetWithCapacity:preferredLocaleIdentifiers.count];
for (NSString *localeIdentifier in preferredLocaleIdentifiers) {
[acceptedLanguages addObject:localeIdentifier];
[acceptedLanguages addObject:[NSLocale localeWithLocaleIdentifier:localeIdentifier].languageCode];
}
auto *acceptedLanguagesString = Util::constructJSArrayOfStrings(acceptedLanguages.array);
auto *preferredLanguagesString = Util::constructJSArrayOfStrings(preferredLocaleIdentifiers);
auto *backgroundScript = Util::constructScript(@[
[NSString stringWithFormat:@"const acceptedLanguages = %@", acceptedLanguagesString],
[NSString stringWithFormat:@"const preferredLanguages = %@", preferredLanguagesString],
[NSString stringWithFormat:@"const currentUILanguage = '%@'", currentLocaleString],
[NSString stringWithFormat:@"const currentSystemUILanguage = '%@'", currentSystemLocaleString],
@"browser.test.assertEq(browser.i18n.getMessage('@@extension_id'), '76C788B8-3374-400D-8259-40E5B9DF79D3')",
@"browser.test.assertEq(browser.i18n.getMessage('@@ui_locale'), '')",
@"browser.test.assertEq(browser.i18n.getMessage('@@bidi_dir'), '')",
@"browser.test.assertEq(browser.i18n.getMessage('@@bidi_reversed_dir'), '')",
@"browser.test.assertEq(browser.i18n.getMessage('@@bidi_start_edge'), '')",
@"browser.test.assertEq(browser.i18n.getMessage('@@bidi_end_edge'), '')",
@"browser.test.assertEq(browser.i18n.getMessage('unknown_message'), '')",
@"browser.test.assertFalse(currentUILanguage === 'und')",
@"browser.test.assertEq(browser.i18n.getUILanguage(), currentUILanguage)",
@"browser.test.assertDeepEq(await browser.i18n.getAcceptLanguages(), acceptedLanguages)",
@"browser.test.assertFalse(currentSystemUILanguage === 'und')",
@"browser.test.assertEq(await browser.i18n.getSystemUILanguage(), currentSystemUILanguage)",
@"browser.test.assertDeepEq(await browser.i18n.getPreferredSystemLanguages(), preferredLanguages)",
@"browser.test.notifyPass()",
]);
auto manager = Util::parseExtension(localizationManifest, @{ @"background.js": backgroundScript });
// Set a base URL so it is a known value and not the default random one.
[WKWebExtensionMatchPattern registerCustomURLScheme:@"test-extension"];
manager.get().context.baseURL = [NSURL URLWithString:baseURLString];
[manager loadAndRun];
}
TEST(WKWebExtensionAPILocalization, i18nWithoutDefaultLocale)
{
NSArray<NSString *> *preferredLocaleIdentifiers = NSLocale.preferredLanguages;
NSMutableOrderedSet<NSString *> *acceptedLanguages = [NSMutableOrderedSet orderedSetWithCapacity:preferredLocaleIdentifiers.count];
for (NSString *localeIdentifier in preferredLocaleIdentifiers) {
[acceptedLanguages addObject:localeIdentifier];
[acceptedLanguages addObject:[NSLocale localeWithLocaleIdentifier:localeIdentifier].languageCode];
}
auto *manifestWithoutLocale = @{
@"manifest_version": @3,
@"name": @"Localization Test",
@"description": @"Localization Test",
@"version": @"1",
@"background": @{
@"scripts": @[ @"background.js" ],
@"type": @"module",
@"persistent": @NO,
}
};
auto *acceptedLanguagesString = Util::constructJSArrayOfStrings(acceptedLanguages.array);
auto *preferredLanguagesString = Util::constructJSArrayOfStrings(preferredLocaleIdentifiers);
auto *backgroundScript = Util::constructScript(@[
[NSString stringWithFormat:@"const acceptedLanguages = %@", acceptedLanguagesString],
[NSString stringWithFormat:@"const preferredLanguages = %@", preferredLanguagesString],
[NSString stringWithFormat:@"const currentUILanguage = '%@'", currentLocaleString],
[NSString stringWithFormat:@"const currentSystemUILanguage = '%@'", currentSystemLocaleString],
@"browser.test.assertEq(browser.i18n.getMessage('@@extension_id'), '76C788B8-3374-400D-8259-40E5B9DF79D3')",
@"browser.test.assertEq(browser.i18n.getMessage('@@ui_locale'), '')",
@"browser.test.assertEq(browser.i18n.getMessage('@@bidi_dir'), '')",
@"browser.test.assertEq(browser.i18n.getMessage('@@bidi_reversed_dir'), '')",
@"browser.test.assertEq(browser.i18n.getMessage('@@bidi_start_edge'), '')",
@"browser.test.assertEq(browser.i18n.getMessage('@@bidi_end_edge'), '')",
@"browser.test.assertEq(browser.i18n.getMessage('unknown_message'), '')",
@"browser.test.assertFalse(currentUILanguage === 'und')",
@"browser.test.assertEq(browser.i18n.getUILanguage(), currentUILanguage)",
@"browser.test.assertDeepEq(await browser.i18n.getAcceptLanguages(), acceptedLanguages)",
@"browser.test.assertFalse(currentSystemUILanguage === 'und')",
@"browser.test.assertEq(await browser.i18n.getSystemUILanguage(), currentSystemUILanguage)",
@"browser.test.assertDeepEq(await browser.i18n.getPreferredSystemLanguages(), preferredLanguages)",
@"browser.test.notifyPass()",
]);
auto manager = Util::parseExtension(manifestWithoutLocale, @{ @"background.js": backgroundScript });
// Set a base URL so it is a known value and not the default random one.
[WKWebExtensionMatchPattern registerCustomURLScheme:@"test-extension"];
manager.get().context.baseURL = [NSURL URLWithString:baseURLString];
[manager loadAndRun];
}
TEST(WKWebExtensionAPILocalization, Placeholders)
{
NSDictionary *localizationDictionary = @{
@"key1": @{
messageKey: @"$placeholder$",
placeholdersKey: @{
@"placeholder": @{
placeholderDictionaryContentKey: @"replacement value",
},
},
},
@"key2": @{
messageKey: @"$Placeholder$ + $PlAcEhOlDeR$",
placeholdersKey: @{
@"placeholder": @{
placeholderDictionaryContentKey: @"replacement value",
},
},
},
@"key3": @{
messageKey: @"$placeholder$ and $place_holder$",
placeholdersKey: @{
@"placeholder": @{
placeholderDictionaryContentKey: @"replacement value",
},
@"pLaCe_hoLder": @{
placeholderDictionaryContentKey: @"different value",
},
},
},
@"key4": @{
messageKey: @"$placeholder$ with $$5",
placeholdersKey: @{
@"unusedplaceholder": @{
placeholderDictionaryContentKey: @"replacement value",
},
},
},
@"key5": @{
messageKey: @"$placeholder$ and $positional$",
placeholdersKey: @{
@"unusedplaceholder": @{
placeholderDictionaryContentKey: @"replacement value",
},
@"positional": @{
placeholderDictionaryContentKey: @"$2",
},
},
},
@"key6": @{
messageKey: @"$1 and $2 but not $3 or $0",
placeholdersKey: @{
@"unusedplaceholder": @{
placeholderDictionaryContentKey: @"replacement value",
},
},
},
@"key7": @{
messageKey: @"$dontreplaceme or me$ or th$is or $$th$$at$",
placeholdersKey: @{
@"unusedplaceholder": @{
placeholderDictionaryContentKey: @"replacement value",
},
},
},
@"key8": @{
messageKey: @"$total$명, 총 $found$명",
placeholdersKey: @{
@"total": @{
placeholderDictionaryContentKey: @"1234",
},
@"found": @{
placeholderDictionaryContentKey: @"42",
},
},
},
};
auto *backgroundScript = Util::constructScript(@[
// Variable setup
[NSString stringWithFormat:@"var placeholders = %@", Util::constructJSArrayOfStrings(@[ @"irrelevant", @"unused" ])],
// Test predefined localization
@"browser.test.assertEq(browser.i18n.getMessage('key1', placeholders), 'replacement value')",
@"browser.test.assertEq(browser.i18n.getMessage('key2', placeholders), 'replacement value + replacement value')",
@"browser.test.assertEq(browser.i18n.getMessage('key3', placeholders), 'replacement value and different value')",
@"browser.test.assertEq(browser.i18n.getMessage('key4', placeholders), ' with $5')",
@"browser.test.assertEq(browser.i18n.getMessage('key7', placeholders), '$dontreplaceme or me$ or th$is or $th$at$')",
@"browser.test.assertEq(browser.i18n.getMessage('key8', placeholders), '1234명, 총 42명')",
[NSString stringWithFormat:@"placeholders = %@", Util::constructJSArrayOfStrings(@[ @"irrelevant", @"argument value" ])],
@"browser.test.assertEq(browser.i18n.getMessage('key5', placeholders), ' and argument value')",
[NSString stringWithFormat:@"placeholders = %@", Util::constructJSArrayOfStrings(@[ @"value1", @"value2" ])],
@"browser.test.assertEq(browser.i18n.getMessage('key6', placeholders), 'value1 and value2 but not or ')",
// Finish
@"browser.test.notifyPass()",
]);
auto manager = Util::parseExtension(localizationManifest, @{ @"background.js": backgroundScript, @"_locales/en/messages.json": localizationDictionary });
// Set a base URL so it is a known value and not the default random one.
[WKWebExtensionMatchPattern registerCustomURLScheme:@"test-extension"];
manager.get().context.baseURL = [NSURL URLWithString:baseURLString];
[manager loadAndRun];
}
TEST(WKWebExtensionAPILocalization, CSSLocalization)
{
auto *backgroundScript = Util::constructScript(@[
@"browser.test.sendMessage('Load Tab')"
]);
auto *htmlContent = @"<link rel='stylesheet' href='test.css'><script src='test.js'></script>";
auto *cssContent = Util::constructScript(@[
@"body {",
@" content: '__MSG_@@extension_id__';",
@" direction: __MSG_@@bidi_dir__;',",
@" text-align: __MSG_@@bidi_start_edge__;",
@"}"
]);
auto *scriptContent = Util::constructScript(@[
@"window.addEventListener('load', () => {",
@" const bodyStyle = getComputedStyle(document.body)",
@" browser.test.assertEq(bodyStyle.content, '\"76C788B8-3374-400D-8259-40E5B9DF79D3\"', 'The content should be')",
@" browser.test.assertEq(bodyStyle.direction, 'ltr', 'The direction should be')",
@" browser.test.assertEq(bodyStyle.textAlign, 'start', 'The text-align should be')",
@" browser.test.notifyPass()",
@"})"
]);
auto *resources = @{
@"background.js": backgroundScript,
@"test.html": htmlContent,
@"test.js": scriptContent,
@"test.css": cssContent,
@"_locales/en/messages.json": messages
};
auto manager = Util::parseExtension(localizationManifest, resources);
// Set a base URL so it is a known value and not the default random one.
[WKWebExtensionMatchPattern registerCustomURLScheme:@"test-extension"];
manager.get().context.baseURL = [NSURL URLWithString:baseURLString];
[manager load];
[manager runUntilTestMessage:@"Load Tab"];
auto *testPageURL = [NSURL URLWithString:@"test.html" relativeToURL:manager.get().context.baseURL];
[manager.get().defaultTab changeWebViewIfNeededForURL:testPageURL forExtensionContext:manager.get().context];
[manager.get().defaultTab.webView loadRequest:[NSURLRequest requestWithURL:testPageURL]];
[manager run];
}
TEST(WKWebExtensionAPILocalization, CSSLocalizationInContentScript)
{
TestWebKitAPI::HTTPServer server({
{ "/"_s, { { { "Content-Type"_s, "text/html"_s } }, ""_s } },
}, TestWebKitAPI::HTTPServer::Protocol::Http);
auto *manifest = @{
@"manifest_version": @3,
@"default_locale": @"en",
@"name": @"Localization Test",
@"description": @"Localization Test",
@"version": @"1",
@"background": @{
@"scripts": @[ @"background.js" ],
@"type": @"module"
},
@"content_scripts": @[@{
@"matches": @[ @"<all_urls>" ],
@"css": @[ @"content.css" ],
@"js": @[ @"content.js" ]
}]
};
auto *backgroundScript = Util::constructScript(@[
@"browser.test.sendMessage('Load Tab')"
]);
auto *contentStyleSheet = Util::constructScript(@[
@"body {",
@" content: '__MSG_@@extension_id__';",
@" direction: '__MSG_@@bidi_dir__';",
@" text-align: '__MSG_@@bidi_start_edge__';",
@"}"
]);
auto *contentScript = Util::constructScript(@[
@"window.addEventListener('load', () => {",
@" const bodyStyle = getComputedStyle(document.body)",
@" browser.test.assertEq(bodyStyle.content, '\"76C788B8-3374-400D-8259-40E5B9DF79D3\"', 'CSS content should be')",
@" browser.test.assertEq(bodyStyle.direction, 'ltr', 'CSS direction should be')",
@" browser.test.assertEq(bodyStyle.textAlign, 'start', 'CSS text-align should be')",
@" browser.test.notifyPass()",
@"})"
]);
auto *resources = @{
@"background.js": backgroundScript,
@"content.js": contentScript,
@"content.css": contentStyleSheet,
@"_locales/en/messages.json": messages
};
auto manager = Util::parseExtension(manifest, resources);
auto *urlRequest = server.requestWithLocalhost();
[manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forURL:urlRequest.URL];
// Set a base URL so it is a known value and not the default random one.
[WKWebExtensionMatchPattern registerCustomURLScheme:@"test-extension"];
manager.get().context.baseURL = [NSURL URLWithString:baseURLString];
[manager load];
[manager runUntilTestMessage:@"Load Tab"];
[manager.get().defaultTab.webView loadRequest:urlRequest];
[manager run];
}
TEST(WKWebExtensionAPILocalization, CSSLocalizationInRegisteredContentScript)
{
TestWebKitAPI::HTTPServer server({
{ "/"_s, { { { "Content-Type"_s, "text/html"_s } }, ""_s } }
}, TestWebKitAPI::HTTPServer::Protocol::Http);
static auto *localizationManifest = @{
@"manifest_version": @3,
@"default_locale": @"en",
@"name": @"Localization Test",
@"description": @"Localization Test",
@"version": @"1.0",
@"permissions": @[ @"scripting" ],
@"background": @{
@"scripts": @[ @"background.js" ],
@"type": @"module"
}
};
auto *backgroundScript = Util::constructScript(@[
@"await browser.scripting.registerContentScripts([{",
@" id: 'test',",
@" matches: ['<all_urls>'],",
@" css: ['content.css'],",
@" js: ['content.js']",
@"}])",
@"browser.test.sendMessage('Load Tab')"
]);
auto *contentStyleSheet = Util::constructScript(@[
@"body {",
@" content: '__MSG_@@extension_id__';",
@" direction: '__MSG_@@bidi_dir__';",
@" text-align: '__MSG_@@bidi_start_edge__';",
@"}"
]);
auto *contentScript = Util::constructScript(@[
@"window.addEventListener('load', () => {",
@" const bodyStyle = getComputedStyle(document.body)",
@" browser.test.assertEq(bodyStyle.content, '\"76C788B8-3374-400D-8259-40E5B9DF79D3\"', 'CSS content should be')",
@" browser.test.assertEq(bodyStyle.direction, 'ltr', 'CSS direction should be')",
@" browser.test.assertEq(bodyStyle.textAlign, 'start', 'CSS text-align should be')",
@" browser.test.notifyPass()",
@"})"
]);
auto *resources = @{
@"background.js": backgroundScript,
@"content.js": contentScript,
@"content.css": contentStyleSheet,
@"_locales/en/messages.json": messages
};
auto manager = Util::parseExtension(localizationManifest, resources);
auto *urlRequest = server.requestWithLocalhost();
[manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forURL:urlRequest.URL];
// Set a base URL so it is a known value and not the default random one.
[WKWebExtensionMatchPattern registerCustomURLScheme:@"test-extension"];
manager.get().context.baseURL = [NSURL URLWithString:baseURLString];
[manager load];
[manager runUntilTestMessage:@"Load Tab"];
[manager.get().defaultTab.webView loadRequest:urlRequest];
[manager run];
}
TEST(WKWebExtensionAPILocalization, i18nChineseSimplified)
{
// Temporarily set the current locale to Simplified Chinese with the US country code for the test.
[NSUserDefaults.standardUserDefaults setVolatileDomain:@{ @"AppleLanguages": @[ @"zh-Hans-US" ] } forName:NSArgumentDomain];
auto *backgroundScript = Util::constructScript(@[
@"browser.test.assertEq(browser.i18n.getMessage('extension_name'), '简体中文扩展')",
@"browser.test.assertEq(browser.i18n.getMessage('default_name'), 'Default English String')",
@"browser.test.notifyPass()",
]);
auto *defaultMessages = @{
@"default_name": @{
@"message": @"Default English String",
@"description": @"The default name in English."
}
};
auto *simplifiedChineseMessages = @{
@"extension_name": @{
@"message": @"简体中文扩展",
@"description": @"The name of the extension in Simplified Chinese."
}
};
auto *traditionalChineseMessages = @{
@"extension_name": @{
@"message": @"繁體中文擴展",
@"description": @"The name of the extension in Traditional Chinese."
}
};
auto *resources = @{
@"background.js": backgroundScript,
@"_locales/en/messages.json": defaultMessages,
@"_locales/zh_CN/messages.json": simplifiedChineseMessages,
@"_locales/zh_TW/messages.json": traditionalChineseMessages,
};
Util::loadAndRunExtension(localizationManifest, resources);
}
TEST(WKWebExtensionAPILocalization, i18nChineseSimplifiedOnly)
{
// Temporarily set the current locale to Simplified Chinese with the US country code for the test.
[NSUserDefaults.standardUserDefaults setVolatileDomain:@{ @"AppleLanguages": @[ @"zh-Hans-US" ] } forName:NSArgumentDomain];
auto *backgroundScript = Util::constructScript(@[
@"browser.test.assertEq(browser.i18n.getMessage('extension_name'), '简体中文扩展')",
@"browser.test.assertEq(browser.i18n.getMessage('default_name'), 'Default English String')",
@"browser.test.notifyPass()",
]);
auto *defaultMessages = @{
@"default_name": @{
@"message": @"Default English String",
@"description": @"The default name in English."
}
};
auto *traditionalChineseMessages = @{
@"extension_name": @{
@"message": @"简体中文扩展",
@"description": @"The name of the extension in Simplified Chinese."
}
};
auto *resources = @{
@"background.js": backgroundScript,
@"_locales/en/messages.json": defaultMessages,
@"_locales/zh_CN/messages.json": traditionalChineseMessages,
};
Util::loadAndRunExtension(localizationManifest, resources);
}
TEST(WKWebExtensionAPILocalization, i18nChineseSimplifiedScript)
{
// Temporarily set the current locale to Simplified Chinese with the US country code for the test.
[NSUserDefaults.standardUserDefaults setVolatileDomain:@{ @"AppleLanguages": @[ @"zh-Hans-US", @"en-US", @"zh-HK" ] } forName:NSArgumentDomain];
auto *backgroundScript = Util::constructScript(@[
@"browser.test.assertEq(browser.i18n.getMessage('extension_name'), '简体中文扩展')",
@"browser.test.assertEq(browser.i18n.getMessage('default_name'), 'Default English String')",
@"browser.test.notifyPass()",
]);
auto *defaultMessages = @{
@"default_name": @{
@"message": @"Default English String",
@"description": @"The default name in English."
}
};
auto *traditionalChineseMessages = @{
@"extension_name": @{
@"message": @"繁體中文擴展",
@"description": @"The name of the extension in Traditional Chinese."
}
};
auto *simplifiedChineseMessages = @{
@"extension_name": @{
@"message": @"简体中文扩展",
@"description": @"The name of the extension in Simplified Chinese."
}
};
auto *resources = @{
@"background.js": backgroundScript,
@"_locales/en/messages.json": defaultMessages,
@"_locales/zh_Hans/messages.json": simplifiedChineseMessages,
@"_locales/zh_Hant/messages.json": traditionalChineseMessages,
};
Util::loadAndRunExtension(localizationManifest, resources);
}
TEST(WKWebExtensionAPILocalization, i18nChineseTraditional)
{
// Temporarily set the current locale to Traditional Chinese with the US country code for the test.
[NSUserDefaults.standardUserDefaults setVolatileDomain:@{ @"AppleLanguages": @[ @"zh-Hant-US" ] } forName:NSArgumentDomain];
auto *backgroundScript = Util::constructScript(@[
@"browser.test.assertEq(browser.i18n.getMessage('extension_name'), '繁體中文擴展')",
@"browser.test.assertEq(browser.i18n.getMessage('default_name'), 'Default English String')",
@"browser.test.notifyPass()",
]);
auto *defaultMessages = @{
@"default_name": @{
@"message": @"Default English String",
@"description": @"The default name in English."
}
};
auto *simplifiedChineseMessages = @{
@"extension_name": @{
@"message": @"简体中文扩展",
@"description": @"The name of the extension in Simplified Chinese."
}
};
auto *traditionalChineseMessages = @{
@"extension_name": @{
@"message": @"繁體中文擴展",
@"description": @"The name of the extension in Traditional Chinese."
}
};
auto *resources = @{
@"background.js": backgroundScript,
@"_locales/en/messages.json": defaultMessages,
@"_locales/zh_CN/messages.json": simplifiedChineseMessages,
@"_locales/zh_TW/messages.json": traditionalChineseMessages,
};
Util::loadAndRunExtension(localizationManifest, resources);
}
TEST(WKWebExtensionAPILocalization, i18nChineseSimplifiedInTaiwan)
{
// Temporarily set the current locale to Simplified Chinese with the Taiwan country code for the test.
[NSUserDefaults.standardUserDefaults setVolatileDomain:@{ @"AppleLanguages": @[ @"zh-Hans-TW" ] } forName:NSArgumentDomain];
auto *backgroundScript = Util::constructScript(@[
@"browser.test.assertEq(browser.i18n.getMessage('extension_name'), '简体中文扩展')",
@"browser.test.assertEq(browser.i18n.getMessage('default_name'), 'Default English String')",
@"browser.test.notifyPass()",
]);
auto *defaultMessages = @{
@"default_name": @{
@"message": @"Default English String",
@"description": @"The default name in English."
}
};
auto *simplifiedChineseMessages = @{
@"extension_name": @{
@"message": @"简体中文扩展",
@"description": @"The name of the extension in Simplified Chinese."
}
};
auto *traditionalChineseMessages = @{
@"extension_name": @{
@"message": @"繁體中文擴展",
@"description": @"The name of the extension in Traditional Chinese."
}
};
auto *resources = @{
@"background.js": backgroundScript,
@"_locales/en/messages.json": defaultMessages,
@"_locales/zh_CN/messages.json": simplifiedChineseMessages,
@"_locales/zh_TW/messages.json": traditionalChineseMessages,
};
Util::loadAndRunExtension(localizationManifest, resources);
}
TEST(WKWebExtensionAPILocalization, i18nChineseTraditionalInChina)
{
// Temporarily set the current locale to Traditional Chinese with the China country code for the test.
[NSUserDefaults.standardUserDefaults setVolatileDomain:@{ @"AppleLanguages": @[ @"zh-Hant-CN" ] } forName:NSArgumentDomain];
auto *backgroundScript = Util::constructScript(@[
@"browser.test.assertEq(browser.i18n.getMessage('extension_name'), '繁體中文擴展')",
@"browser.test.assertEq(browser.i18n.getMessage('default_name'), 'Default English String')",
@"browser.test.notifyPass()",
]);
auto *defaultMessages = @{
@"default_name": @{
@"message": @"Default English String",
@"description": @"The default name in English."
}
};
auto *simplifiedChineseMessages = @{
@"extension_name": @{
@"message": @"简体中文扩展",
@"description": @"The name of the extension in Simplified Chinese."
}
};
auto *traditionalChineseMessages = @{
@"extension_name": @{
@"message": @"繁體中文擴展",
@"description": @"The name of the extension in Traditional Chinese."
}
};
auto *resources = @{
@"background.js": backgroundScript,
@"_locales/en/messages.json": defaultMessages,
@"_locales/zh_CN/messages.json": simplifiedChineseMessages,
@"_locales/zh_TW/messages.json": traditionalChineseMessages,
};
Util::loadAndRunExtension(localizationManifest, resources);
}
TEST(WKWebExtensionAPILocalization, i18nChineseSimplifiedInHongKong)
{
// Temporarily set the current locale to Simplified Chinese with the Hong Kong country code for the test.
[NSUserDefaults.standardUserDefaults setVolatileDomain:@{ @"AppleLanguages": @[ @"zh-Hans-HK" ] } forName:NSArgumentDomain];
auto *backgroundScript = Util::constructScript(@[
@"browser.test.assertEq(browser.i18n.getMessage('extension_name'), '简体中文扩展')",
@"browser.test.assertEq(browser.i18n.getMessage('default_name'), 'Default English String')",
@"browser.test.notifyPass()",
]);
auto *defaultMessages = @{
@"default_name": @{
@"message": @"Default English String",
@"description": @"The default name in English."
}
};
auto *simplifiedChineseMessages = @{
@"extension_name": @{
@"message": @"简体中文扩展",
@"description": @"The name of the extension in Simplified Chinese."
}
};
auto *traditionalChineseMessages = @{
@"extension_name": @{
@"message": @"繁體中文擴展",
@"description": @"The name of the extension in Traditional Chinese."
}
};
auto *cantoneseMessages = @{
@"extension_name": @{
@"message": @"香港擴展",
@"description": @"The name of the extension in Cantonese (Hong Kong)."
}
};
auto *resources = @{
@"background.js": backgroundScript,
@"_locales/en/messages.json": defaultMessages,
@"_locales/zh_CN/messages.json": simplifiedChineseMessages,
@"_locales/zh_TW/messages.json": traditionalChineseMessages,
@"_locales/zh_HK/messages.json": cantoneseMessages,
};
Util::loadAndRunExtension(localizationManifest, resources);
}
TEST(WKWebExtensionAPILocalization, i18nChineseTraditionalOnly)
{
// Temporarily set the current locale to Traditional Chinese with the US country code for the test.
[NSUserDefaults.standardUserDefaults setVolatileDomain:@{ @"AppleLanguages": @[ @"zh-Hant-US" ] } forName:NSArgumentDomain];
auto *backgroundScript = Util::constructScript(@[
@"browser.test.assertEq(browser.i18n.getMessage('extension_name'), '繁體中文擴展')",
@"browser.test.assertEq(browser.i18n.getMessage('default_name'), 'Default English String')",
@"browser.test.notifyPass()",
]);
auto *defaultMessages = @{
@"default_name": @{
@"message": @"Default English String",
@"description": @"The default name in English."
}
};
auto *traditionalChineseMessages = @{
@"extension_name": @{
@"message": @"繁體中文擴展",
@"description": @"The name of the extension in Traditional Chinese."
}
};
auto *resources = @{
@"background.js": backgroundScript,
@"_locales/en/messages.json": defaultMessages,
@"_locales/zh_TW/messages.json": traditionalChineseMessages,
};
Util::loadAndRunExtension(localizationManifest, resources);
}
TEST(WKWebExtensionAPILocalization, i18nChineseTraditionalScript)
{
// Temporarily set the current locale to Simplified Chinese with the US country code for the test.
[NSUserDefaults.standardUserDefaults setVolatileDomain:@{ @"AppleLanguages": @[ @"zh-Hant-US" ] } forName:NSArgumentDomain];
auto *backgroundScript = Util::constructScript(@[
@"browser.test.assertEq(browser.i18n.getMessage('extension_name'), '繁體中文擴展')",
@"browser.test.assertEq(browser.i18n.getMessage('default_name'), 'Default English String')",
@"browser.test.notifyPass()",
]);
auto *defaultMessages = @{
@"default_name": @{
@"message": @"Default English String",
@"description": @"The default name in English."
}
};
auto *traditionalChineseMessages = @{
@"extension_name": @{
@"message": @"繁體中文擴展",
@"description": @"The name of the extension in Traditional Chinese."
}
};
auto *simplifiedChineseMessages = @{
@"extension_name": @{
@"message": @"简体中文扩展",
@"description": @"The name of the extension in Simplified Chinese."
}
};
auto *resources = @{
@"background.js": backgroundScript,
@"_locales/en/messages.json": defaultMessages,
@"_locales/zh_Hans/messages.json": simplifiedChineseMessages,
@"_locales/zh_Hant/messages.json": traditionalChineseMessages,
};
Util::loadAndRunExtension(localizationManifest, resources);
}
TEST(WKWebExtensionAPILocalization, i18nChineseLanguageFallback)
{
// Temporarily set the current locale to Simplified Chinese in China for the test.
[NSUserDefaults.standardUserDefaults setVolatileDomain:@{ @"AppleLanguages": @[ @"zh-Hans-CN" ] } forName:NSArgumentDomain];
auto *backgroundScript = Util::constructScript(@[
@"browser.test.assertEq(browser.i18n.getMessage('regional_name'), '简体中文扩展')",
@"browser.test.assertEq(browser.i18n.getMessage('language_name'), '中文扩展')",
@"browser.test.assertEq(browser.i18n.getMessage('default_name'), 'Default English String')",
@"browser.test.notifyPass()",
]);
auto *defaultMessages = @{
@"default_name": @{
@"message": @"Default English String",
@"description": @"The default name in English."
}
};
auto *simplifiedChineseMessages = @{
@"regional_name": @{
@"message": @"简体中文扩展",
@"description": @"The name of the extension in Simplified Chinese."
}
};
auto *genericChineseMessages = @{
@"language_name": @{
@"message": @"中文扩展",
@"description": @"The name of the extension in generic Chinese."
}
};
auto *resources = @{
@"background.js": backgroundScript,
@"_locales/en/messages.json": defaultMessages,
@"_locales/zh/messages.json": genericChineseMessages,
@"_locales/zh_CN/messages.json": simplifiedChineseMessages,
};
Util::loadAndRunExtension(localizationManifest, resources);
}
TEST(WKWebExtensionAPILocalization, i18nChineseTraditionalFallback)
{
// Temporarily set the current locale to Traditional Chinese for the test.
[NSUserDefaults.standardUserDefaults setVolatileDomain:@{ @"AppleLanguages": @[ @"zh-Hant" ] } forName:NSArgumentDomain];
auto *backgroundScript = Util::constructScript(@[
@"browser.test.assertEq(browser.i18n.getMessage('language_name'), '中文擴展', 'Generic Chinese message should be used')",
@"browser.test.assertEq(browser.i18n.getMessage('default_name'), 'Default English String', 'Default fallback message should be used')",
@"browser.test.notifyPass()",
]);
auto *defaultMessages = @{
@"default_name": @{
@"message": @"Default English String",
@"description": @"The default name in English."
}
};
auto *genericChineseMessages = @{
@"language_name": @{
@"message": @"中文擴展",
@"description": @"The name of the extension in Chinese."
}
};
auto *resources = @{
@"background.js": backgroundScript,
@"_locales/en/messages.json": defaultMessages,
@"_locales/zh/messages.json": genericChineseMessages,
};
auto extension = adoptNS([[WKWebExtension alloc] _initWithManifestDictionary:localizationManifest resources:resources]);
auto manager = adoptNS([[TestWebExtensionManager alloc] initForExtension:extension.get()]);
[manager loadAndRun];
}
TEST(WKWebExtensionAPILocalization, i18nChineseSimplifiedFallback)
{
// Temporarily set the current locale to Simplified Chinese for the test.
[NSUserDefaults.standardUserDefaults setVolatileDomain:@{ @"AppleLanguages": @[ @"zh-Hans" ] } forName:NSArgumentDomain];
auto *backgroundScript = Util::constructScript(@[
@"browser.test.assertEq(browser.i18n.getMessage('language_name'), '中文扩展', 'Generic Chinese message should be used')",
@"browser.test.assertEq(browser.i18n.getMessage('default_name'), 'Default English String', 'Default fallback message should be used')",
@"browser.test.notifyPass()",
]);
auto *defaultMessages = @{
@"default_name": @{
@"message": @"Default English String",
@"description": @"The default name in English."
}
};
auto *genericChineseMessages = @{
@"language_name": @{
@"message": @"中文扩展",
@"description": @"The name of the extension in Simplified Chinese."
}
};
auto *resources = @{
@"background.js": backgroundScript,
@"_locales/en/messages.json": defaultMessages,
@"_locales/zh/messages.json": genericChineseMessages,
};
auto extension = adoptNS([[WKWebExtension alloc] _initWithManifestDictionary:localizationManifest resources:resources]);
auto manager = adoptNS([[TestWebExtensionManager alloc] initForExtension:extension.get()]);
[manager loadAndRun];
}
TEST(WKWebExtensionAPILocalization, i18nPortugueseBrazilian)
{
// Temporarily set the current locale to Brazilian Portuguese for the test.
[NSUserDefaults.standardUserDefaults setVolatileDomain:@{ @"AppleLanguages": @[ @"pt-BR" ] } forName:NSArgumentDomain];
auto *backgroundScript = Util::constructScript(@[
@"browser.test.assertEq(browser.i18n.getMessage('extension_name'), 'Extensão Brasileira')",
@"browser.test.assertEq(browser.i18n.getMessage('default_name'), 'Default English String')",
@"browser.test.notifyPass()",
]);
auto *defaultMessages = @{
@"default_name": @{
@"message": @"Default English String",
@"description": @"The default name in English."
}
};
auto *brazilianPortugueseMessages = @{
@"extension_name": @{
@"message": @"Extensão Brasileira",
@"description": @"The name of the extension in Brazilian Portuguese."
}
};
auto *resources = @{
@"background.js": backgroundScript,
@"_locales/en/messages.json": defaultMessages,
@"_locales/pt_BR/messages.json": brazilianPortugueseMessages,
};
Util::loadAndRunExtension(localizationManifest, resources);
}
TEST(WKWebExtensionAPILocalization, i18nPortugueseEuropean)
{
// Temporarily set the current locale to European Portuguese for the test.
[NSUserDefaults.standardUserDefaults setVolatileDomain:@{ @"AppleLanguages": @[ @"pt-PT" ] } forName:NSArgumentDomain];
auto *backgroundScript = Util::constructScript(@[
@"browser.test.assertEq(browser.i18n.getMessage('extension_name'), 'Extensão Portuguesa')",
@"browser.test.assertEq(browser.i18n.getMessage('default_name'), 'Default English String')",
@"browser.test.notifyPass()",
]);
auto *defaultMessages = @{
@"default_name": @{
@"message": @"Default English String",
@"description": @"The default name in English."
}
};
auto *europeanPortugueseMessages = @{
@"extension_name": @{
@"message": @"Extensão Portuguesa",
@"description": @"The name of the extension in European Portuguese."
}
};
auto *resources = @{
@"background.js": backgroundScript,
@"_locales/en/messages.json": defaultMessages,
@"_locales/pt_PT/messages.json": europeanPortugueseMessages,
};
Util::loadAndRunExtension(localizationManifest, resources);
}
TEST(WKWebExtensionAPILocalization, i18nPortugueseUnitedStates)
{
// Temporarily set the current locale to Portuguese with the US country code for the test.
[NSUserDefaults.standardUserDefaults setVolatileDomain:@{ @"AppleLanguages": @[ @"pt-US" ] } forName:NSArgumentDomain];
auto *backgroundScript = Util::constructScript(@[
@"browser.test.assertEq(browser.i18n.getMessage('extension_name'), 'Extensão Portuguesa')",
@"browser.test.assertEq(browser.i18n.getMessage('default_name'), 'Default English String')",
@"browser.test.notifyPass()",
]);
auto *defaultMessages = @{
@"default_name": @{
@"message": @"Default English String",
@"description": @"The default name in English."
}
};
auto *europeanPortugueseMessages = @{
@"extension_name": @{
@"message": @"Extensão Portuguesa",
@"description": @"The name of the extension in European Portuguese."
}
};
auto *resources = @{
@"background.js": backgroundScript,
@"_locales/en/messages.json": defaultMessages,
@"_locales/pt_PT/messages.json": europeanPortugueseMessages,
};
Util::loadAndRunExtension(localizationManifest, resources);
}
TEST(WKWebExtensionAPILocalization, i18nPortugueseUnitedStatesFallbackToBrazilian)
{
// Temporarily set the current locale to Portuguese with the US country code for the test.
[NSUserDefaults.standardUserDefaults setVolatileDomain:@{ @"AppleLanguages": @[ @"pt-US" ] } forName:NSArgumentDomain];
auto *backgroundScript = Util::constructScript(@[
@"browser.test.assertEq(browser.i18n.getMessage('extension_name'), 'Extensão Brasileira')",
@"browser.test.assertEq(browser.i18n.getMessage('default_name'), 'Default English String')",
@"browser.test.notifyPass()",
]);
auto *defaultMessages = @{
@"default_name": @{
@"message": @"Default English String",
@"description": @"The default name in English."
}
};
auto *brazilianPortugueseMessages = @{
@"extension_name": @{
@"message": @"Extensão Brasileira",
@"description": @"The name of the extension in Brazilian Portuguese."
}
};
auto *europeanPortugueseMessages = @{
@"extension_name": @{
@"message": @"Extensão Portuguesa",
@"description": @"The name of the extension in European Portuguese."
}
};
auto *resources = @{
@"background.js": backgroundScript,
@"_locales/en/messages.json": defaultMessages,
@"_locales/pt_BR/messages.json": brazilianPortugueseMessages,
@"_locales/pt_PT/messages.json": europeanPortugueseMessages,
};
Util::loadAndRunExtension(localizationManifest, resources);
}
TEST(WKWebExtensionAPILocalization, i18nPortugueseUnitedStatesFallbackToGeneric)
{
// Temporarily set the current locale to Portuguese with the US country code for the test.
[NSUserDefaults.standardUserDefaults setVolatileDomain:@{ @"AppleLanguages": @[ @"pt-US" ] } forName:NSArgumentDomain];
auto *backgroundScript = Util::constructScript(@[
@"browser.test.assertEq(browser.i18n.getMessage('extension_name'), 'Extensão Portuguesa Genérica')",
@"browser.test.assertEq(browser.i18n.getMessage('default_name'), 'Default English String')",
@"browser.test.notifyPass()",
]);
auto *defaultMessages = @{
@"default_name": @{
@"message": @"Default English String",
@"description": @"The default name in English."
}
};
auto *genericPortugueseMessages = @{
@"extension_name": @{
@"message": @"Extensão Portuguesa Genérica",
@"description": @"The name of the extension in generic Portuguese."
}
};
auto *europeanPortugueseMessages = @{
@"extension_name": @{
@"message": @"Extensão Portuguesa",
@"description": @"The name of the extension in European Portuguese."
}
};
auto *resources = @{
@"background.js": backgroundScript,
@"_locales/en/messages.json": defaultMessages,
@"_locales/pt/messages.json": genericPortugueseMessages,
@"_locales/pt_PT/messages.json": europeanPortugueseMessages,
};
Util::loadAndRunExtension(localizationManifest, resources);
}
TEST(WKWebExtensionAPILocalization, i18nPortugueseLanguageFallback)
{
// Temporarily set the current locale to Brazilian Portuguese for the test.
[NSUserDefaults.standardUserDefaults setVolatileDomain:@{ @"AppleLanguages": @[ @"pt-BR" ] } forName:NSArgumentDomain];
auto *backgroundScript = Util::constructScript(@[
@"browser.test.assertEq(browser.i18n.getMessage('regional_name'), 'Extensão Brasileira')",
@"browser.test.assertEq(browser.i18n.getMessage('language_name'), 'Extensão Portuguesa Genérica')",
@"browser.test.assertEq(browser.i18n.getMessage('default_name'), 'Default English String')",
@"browser.test.notifyPass()",
]);
auto *defaultMessages = @{
@"default_name": @{
@"message": @"Default English String",
@"description": @"The default name in English."
}
};
auto *brazilianPortugueseMessages = @{
@"regional_name": @{
@"message": @"Extensão Brasileira",
@"description": @"The name of the extension in Brazilian Portuguese."
}
};
auto *genericPortugueseMessages = @{
@"language_name": @{
@"message": @"Extensão Portuguesa Genérica",
@"description": @"The name of the extension in generic Portuguese."
}
};
auto *resources = @{
@"background.js": backgroundScript,
@"_locales/en/messages.json": defaultMessages,
@"_locales/pt/messages.json": genericPortugueseMessages,
@"_locales/pt_BR/messages.json": brazilianPortugueseMessages,
};
Util::loadAndRunExtension(localizationManifest, resources);
}
TEST(WKWebExtensionAPILocalization, i18nSpanishLatinAmerica)
{
// Temporarily set the current locale to Latin American Spanish.
[NSUserDefaults.standardUserDefaults setVolatileDomain:@{ @"AppleLanguages": @[ @"es-419" ] } forName:NSArgumentDomain];
auto *backgroundScript = Util::constructScript(@[
@"browser.test.assertEq(browser.i18n.getMessage('extension_name'), 'Extensión en español')",
@"browser.test.assertEq(browser.i18n.getMessage('default_name'), 'Default English String')",
@"browser.test.notifyPass()",
]);
auto *defaultMessages = @{
@"default_name": @{
@"message": @"Default English String",
@"description": @"The default name in English."
}
};
auto *latinAmericanSpanishMessages = @{
@"extension_name": @{
@"message": @"Extensión en español",
@"description": @"The name of the extension in Latin American Spanish."
}
};
auto *castilianSpanishMessages = @{
@"extension_name": @{
@"message": @"Extensión en castellano",
@"description": @"The name of the extension in Castilian Spanish."
}
};
auto *resources = @{
@"background.js": backgroundScript,
@"_locales/en/messages.json": defaultMessages,
@"_locales/es_419/messages.json": latinAmericanSpanishMessages,
@"_locales/es_ES/messages.json": castilianSpanishMessages,
};
Util::loadAndRunExtension(localizationManifest, resources);
}
TEST(WKWebExtensionAPILocalization, i18nSpanishMexico)
{
// Temporarily set the current locale to Spanish (Mexico).
[NSUserDefaults.standardUserDefaults setVolatileDomain:@{ @"AppleLanguages": @[ @"es-MX" ] } forName:NSArgumentDomain];
auto *backgroundScript = Util::constructScript(@[
@"browser.test.assertEq(browser.i18n.getMessage('extension_name'), 'Extensión en español')",
@"browser.test.assertEq(browser.i18n.getMessage('default_name'), 'Default English String')",
@"browser.test.notifyPass()",
]);
auto *defaultMessages = @{
@"default_name": @{
@"message": @"Default English String",
@"description": @"The default name in English."
}
};
auto *latinAmericanSpanishMessages = @{
@"extension_name": @{
@"message": @"Extensión en español",
@"description": @"The name of the extension in Latin American Spanish."
}
};
auto *castilianSpanishMessages = @{
@"extension_name": @{
@"message": @"Extensión en castellano",
@"description": @"The name of the extension in Castilian Spanish."
}
};
auto *resources = @{
@"background.js": backgroundScript,
@"_locales/en/messages.json": defaultMessages,
@"_locales/es_419/messages.json": latinAmericanSpanishMessages,
@"_locales/es_ES/messages.json": castilianSpanishMessages,
};
Util::loadAndRunExtension(localizationManifest, resources);
}
TEST(WKWebExtensionAPILocalization, i18nSpanishSpain)
{
// Temporarily set the current locale to Spanish (Spain).
[NSUserDefaults.standardUserDefaults setVolatileDomain:@{ @"AppleLanguages": @[ @"es-ES" ] } forName:NSArgumentDomain];
auto *backgroundScript = Util::constructScript(@[
@"browser.test.assertEq(browser.i18n.getMessage('extension_name'), 'Extensión en castellano')",
@"browser.test.assertEq(browser.i18n.getMessage('default_name'), 'Default English String')",
@"browser.test.notifyPass()",
]);
auto *defaultMessages = @{
@"default_name": @{
@"message": @"Default English String",
@"description": @"The default name in English."
}
};
auto *castilianSpanishMessages = @{
@"extension_name": @{
@"message": @"Extensión en castellano",
@"description": @"The name of the extension in Castilian Spanish."
}
};
auto *latinAmericanSpanishMessages = @{
@"extension_name": @{
@"message": @"Extensión en español",
@"description": @"The name of the extension in Latin American Spanish."
}
};
auto *resources = @{
@"background.js": backgroundScript,
@"_locales/en/messages.json": defaultMessages,
@"_locales/es_ES/messages.json": castilianSpanishMessages,
@"_locales/es_419/messages.json": latinAmericanSpanishMessages,
};
Util::loadAndRunExtension(localizationManifest, resources);
}
TEST(WKWebExtensionAPILocalization, i18nSwedishDefaultToEnglish)
{
// Temporarily set the current locale to Swedish (Sweden) for the test.
[NSUserDefaults.standardUserDefaults setVolatileDomain:@{ @"AppleLanguages": @[ @"sv-SE" ] } forName:NSArgumentDomain];
auto *backgroundScript = Util::constructScript(@[
@"browser.test.assertEq(browser.i18n.getMessage('extension_name'), 'Default English Name', 'Should fall back to the default English name.')",
@"browser.test.assertEq(browser.i18n.getMessage('default_description'), 'Default English Description', 'Should fall back to the default English description.')",
@"browser.test.notifyPass()",
]);
auto *defaultMessages = @{
@"extension_name": @{
@"message": @"Default English Name",
@"description": @"The name of the extension in English."
},
@"default_description": @{
@"message": @"Default English Description",
@"description": @"A default description in English."
}
};
auto *resources = @{
@"background.js": backgroundScript,
@"_locales/en/messages.json": defaultMessages,
};
Util::loadAndRunExtension(localizationManifest, resources);
}
} // namespace TestWebKitAPI
#endif // ENABLE(WK_WEB_EXTENSIONS)