e2e: add tests for translations (#114390)

e2e: add tests for translations
This commit is contained in:
Hugo Häggmark
2025-12-08 10:19:44 +01:00
committed by GitHub
parent 8bf3ac9710
commit 3490c3b0fd
46 changed files with 678 additions and 20 deletions
@@ -1,6 +1,7 @@
import { ChangeEvent } from 'react';
import { Checkbox, InlineField, InlineSwitch, Input, SecretInput, Select } from '@grafana/ui';
import { DataSourcePluginOptionsEditorProps, SelectableValue, toOption } from '@grafana/data';
import { t } from '@grafana/i18n';
import { MyDataSourceOptions, MySecureJsonData } from '../types';
interface Props extends DataSourcePluginOptionsEditorProps<MyDataSourceOptions, MySecureJsonData> {}
@@ -45,36 +46,46 @@ export function ConfigEditor(props: Props) {
return (
<>
<InlineField label="Path" labelWidth={14} interactive tooltip={'Json field returned to frontend'}>
<InlineField
label={t('config-editor.path.label', 'Path')}
labelWidth={14}
interactive
tooltip={t('config-editor.path.tooltip', 'Json field returned to frontend')}
>
<Input
id="config-editor-path"
onChange={(e: ChangeEvent<HTMLInputElement>) => onJsonDataChange('path', e.target.value)}
value={jsonData.path}
placeholder="Enter the path, e.g. /api/v1"
placeholder={t('config-editor.path.placeholder', 'Enter the path, e.g. /api/v1')}
width={40}
/>
</InlineField>
<InlineField label="API Key" labelWidth={14} interactive tooltip={'Secure json field (backend only)'}>
<InlineField
label={t('config-editor.api-key.label', 'API Key')}
labelWidth={14}
interactive
tooltip={t('config-editor.api-key.tooltip', 'Secure json field (backend only)')}
>
<SecretInput
required
id="config-editor-api-key"
isConfigured={secureJsonFields.apiKey}
value={secureJsonData?.apiKey}
placeholder="Enter your API key"
placeholder={t('config-editor.api-key.placeholder', 'Enter your API key')}
width={40}
onReset={onResetAPIKey}
onChange={(e: ChangeEvent<HTMLInputElement>) => onSecureJsonDataChange('path', e.target.value)}
/>
</InlineField>
<InlineField label="Switch Enabled">
<InlineField label={t('config-editor.switch-enabled.label', 'Switch Enabled')}>
<InlineSwitch
width={40}
label="Switch Enabled"
label={t('config-editor.switch-enabled.label', 'Switch Enabled')}
value={jsonData.switchEnabled ?? false}
onChange={(e: ChangeEvent<HTMLInputElement>) => onJsonDataChange('switchEnabled', e.target.checked)}
/>
</InlineField>
<InlineField label="Checkbox Enabled">
<InlineField label={t('config-editor.checkbox-enabled.label', 'Checkbox Enabled')}>
<Checkbox
width={40}
id="config-checkbox-enabled"
@@ -82,7 +93,7 @@ export function ConfigEditor(props: Props) {
onChange={(e: ChangeEvent<HTMLInputElement>) => onJsonDataChange('checkboxEnabled', e.target.checked)}
/>
</InlineField>
<InlineField label="Auth type">
<InlineField label={t('config-editor.auth-type.label', 'Auth type')}>
<Select
width={40}
inputId="config-auth-type"
@@ -0,0 +1,13 @@
import { defineConfig } from 'i18next-cli';
import pluginJson from './plugin.json';
export default defineConfig({
locales: pluginJson.languages,
extract: {
input: ['**/*.{tsx,ts}'],
output: 'locales/{{language}}/{{namespace}}.json',
defaultNS: pluginJson.id,
functions: ['t', '*.t'],
transComponents: ['Trans'],
},
});
@@ -0,0 +1,23 @@
{
"config-editor": {
"api-key": {
"label": "API Key",
"placeholder": "Enter your API key",
"tooltip": "Secure json field (backend only)"
},
"auth-type": {
"label": "Auth type"
},
"checkbox-enabled": {
"label": "Checkbox Enabled"
},
"path": {
"label": "Path",
"placeholder": "Enter the path, e.g. /api/v1",
"tooltip": "Json field returned to frontend"
},
"switch-enabled": {
"label": "Switch Enabled"
}
}
}
@@ -0,0 +1,23 @@
{
"config-editor": {
"api-key": {
"label": "Clave de API",
"placeholder": "Ingrese su clave de API",
"tooltip": "Campo JSON seguro (solo backend)"
},
"auth-type": {
"label": "Tipo de autenticación"
},
"checkbox-enabled": {
"label": "Casilla habilitada"
},
"path": {
"label": "Ruta",
"placeholder": "Ingrese la ruta, p. ej. /api/v1",
"tooltip": "Campo JSON devuelto al frontend"
},
"switch-enabled": {
"label": "Interruptor habilitado"
}
}
}
@@ -0,0 +1,23 @@
{
"config-editor": {
"api-key": {
"label": "API-nyckel",
"placeholder": "Ange din API-nyckel",
"tooltip": "Säkert json-fält (endast backend)"
},
"auth-type": {
"label": "Autentiseringstyp"
},
"checkbox-enabled": {
"label": "Kryssruta aktiverad"
},
"path": {
"label": "Sökväg",
"placeholder": "Ange sökvägen, t.ex. /api/v1",
"tooltip": "Json-fält som returneras till frontend"
},
"switch-enabled": {
"label": "Omkopplare aktiverad"
}
}
}
@@ -3,6 +3,10 @@ import { DataSource } from './datasource';
import { ConfigEditor } from './components/ConfigEditor';
import { QueryEditor } from './components/QueryEditor';
import { MyQuery, MyDataSourceOptions } from './types';
import pluginJson from './plugin.json';
import { initPluginTranslations } from '@grafana/i18n';
await initPluginTranslations(pluginJson.id);
export const plugin = new DataSourcePlugin<DataSource, MyQuery, MyDataSourceOptions>(DataSource)
.setConfigEditor(ConfigEditor)
@@ -6,7 +6,8 @@
"build": "NODE_OPTIONS='--experimental-strip-types --no-warnings=ExperimentalWarning' webpack -c ./webpack.config.ts --env production",
"dev": "NODE_OPTIONS='--experimental-strip-types --no-warnings=ExperimentalWarning' webpack -w -c ./webpack.config.ts --env development",
"typecheck": "tsc --noEmit",
"lint": "eslint --cache --ignore-path ./.gitignore --ext .js,.jsx,.ts,.tsx ."
"lint": "eslint --cache --ignore-path ./.gitignore --ext .js,.jsx,.ts,.tsx .",
"i18n-extract": "i18next-cli extract --sync-primary"
},
"author": "Grafana",
"license": "Apache-2.0",
@@ -20,17 +21,19 @@
"@types/semver": "7.5.8",
"@types/uuid": "9.0.8",
"glob": "10.4.1",
"i18next-cli": "^1.24.22",
"ts-node": "10.9.2",
"typescript": "5.5.4",
"webpack": "5.95.0",
"webpack-merge": "5.10.0"
},
"engines": {
"node": ">=20"
"node": ">= 22 <25"
},
"dependencies": {
"@emotion/css": "11.11.2",
"@grafana/data": "workspace:*",
"@grafana/i18n": "workspace:*",
"@grafana/runtime": "workspace:*",
"@grafana/schema": "workspace:*",
"@grafana/ui": "workspace:*",
@@ -43,5 +46,5 @@
"peerDependencies": {
"@grafana/runtime": "*"
},
"packageManager": "yarn@4.4.0"
"packageManager": "yarn@4.11.0"
}
@@ -20,7 +20,8 @@
"updated": "%TODAY%"
},
"dependencies": {
"grafanaDependency": ">=10.4.0",
"grafanaDependency": ">=12.0.0",
"plugins": []
}
},
"languages": ["en-US", "es-ES", "sv-SE"]
}
@@ -0,0 +1,11 @@
import { FRENCH_FRANCE } from '@grafana/i18n';
import { expect, test } from '@grafana/plugin-e2e';
import pluginJson from '../../plugin.json';
test.use({ userPreferences: { language: FRENCH_FRANCE } });
test('should display default translation (en-US)', async ({ createDataSourceConfigPage }) => {
const configPage = await createDataSourceConfigPage({ type: pluginJson.id });
await expect(configPage.ctx.page.getByLabel('API Key')).toBeVisible();
});
@@ -0,0 +1,11 @@
import { SWEDISH_SWEDEN } from '@grafana/i18n';
import { expect, test } from '@grafana/plugin-e2e';
import pluginJson from '../../plugin.json';
test.use({ userPreferences: { language: SWEDISH_SWEDEN } });
test('should display correct translation', async ({ createDataSourceConfigPage }) => {
const configPage = await createDataSourceConfigPage({ type: pluginJson.id });
await expect(configPage.ctx.page.getByLabel('API-nyckel')).toBeVisible();
});
@@ -34,6 +34,7 @@ const config = async (env: Env): Promise<Configuration> => {
],
}),
],
externals: [...(baseConfig.externals as any), 'i18next'],
};
return mergeWithCustomize({