pytests: Migrate to new i18n library.

Change pytests to use the new i18n library.

BUG=chromium:678434
TEST=make test

Change-Id: I5d0c3595666eb6d027a00d44d65c27215bacbfb2
Reviewed-on: https://chromium-review.googlesource.com/442288
Commit-Ready: Pi-Hsun Shih <pihsun@chromium.org>
Tested-by: Pi-Hsun Shih <pihsun@chromium.org>
Reviewed-by: Hung-Te Lin <hungte@chromium.org>
diff --git a/po/zh-CN.po b/po/zh-CN.po
index 905a496..fe37bd9 100644
--- a/po/zh-CN.po
+++ b/po/zh-CN.po
@@ -4,7 +4,7 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: ChromeOS Factory Software\n"
-"POT-Creation-Date: 2017-02-24 13:41+CST\n"
+"POT-Creation-Date: 2017-03-01 17:22+CST\n"
 "PO-Revision-Date: 2017-01-05 07:36+CST\n"
 "Last-Translator: ChromeOS Factory Team\n"
 "Language-Team: ChromeOS Factory Team\n"
@@ -14,6 +14,86 @@
 "Content-Transfer-Encoding: 8bit\n"
 "Generated-By: pygettext.py 1.5\n"
 
+#: ../py/test/pytests/ac_power.py
+msgid "Connect AC"
+msgstr "连接充电器"
+
+#: ../py/test/pytests/ac_power.py
+msgid "Remove AC"
+msgstr "移除充电器"
+
+#: ../py/test/pytests/ac_power.py
+msgid "Plug in the charger ({type})"
+msgstr "请连接充电器 ({type})"
+
+#: ../py/test/pytests/ac_power.py
+msgid "Plug in the charger"
+msgstr "请连接充电器"
+
+#: ../py/test/pytests/ac_power.py
+msgid "Unplug the charger."
+msgstr "请移除充电器"
+
+#: ../py/test/pytests/ac_power.py
+msgid "Probed {times} / {total}"
+msgstr "侦测次数 {times} / {total}"
+
+#: ../py/test/pytests/ac_power.py
+msgid "No AC adapter"
+msgstr "没有充电器"
+
+#: ../py/test/pytests/ac_power.py
+msgid "Identifying AC adapter..."
+msgstr "充电器型号识别中..."
+
+#: ../py/test/pytests/ac_power.py
+msgid "AC adapter type: "
+msgstr "充电器型号: "
+
+#: ../py/test/pytests/accelerometers_calibration.py
+msgid "ERROR: The function is not supported."
+msgstr "此功能尚未支持。"
+
+#: ../py/test/pytests/accelerometers_calibration.py
+#: ../py/test/pytests/gyroscope.py
+msgid ""
+"Please put device on a horizontal plane then press space to start "
+"calibration."
+msgstr "请将待测物放置于水平面上,并按空白键开始校准。"
+
+#: ../py/test/pytests/accelerometers_calibration.py
+msgid ""
+"Calibration will be started within {time} seconds.Please do not move device."
+msgstr "校准程序即将于 {time} 秒后开始,请勿移动待测物。"
+
+#: ../py/test/pytests/accelerometers_calibration.py
+msgid "Calibration is in progress, please do not move device."
+msgstr "校准程序进行中,请勿移动待测物。"
+
+#: ../py/test/pytests/accelerometers_calibration.py
+#: ../py/test/pytests/gyroscope.py ../py/test/pytests/sensor_movement.py
+#: ../py/test/pytests/touchscreen_uniformity.py
+msgid "PASS"
+msgstr "成功"
+
+#: ../py/test/pytests/accelerometers_calibration.py
+#: ../py/test/pytests/gyroscope.py ../py/test/pytests/sensor_movement.py
+#: ../py/test/pytests/touchscreen_uniformity.py
+msgid "FAIL"
+msgstr "失败"
+
+#: ../py/test/pytests/accelerometers_lid_angle.py
+msgid "Please open the lid to {angle} degrees."
+msgstr "请将上盖掀开到 {angle} 度。"
+
+#: ../py/test/pytests/accelerometers_lid_angle.py
+msgid "Confirm {angle} degrees"
+msgstr "确认掀开到 {angle} 度"
+
+#: ../py/test/pytests/accelerometers_lid_angle.py
+msgid "Checking angle..."
+msgstr "正在确认角度……"
+
 #: ../py/test/pytests/audio.py
 msgid "Audio Test"
 msgstr "音讯测试"
@@ -52,11 +132,270 @@
 msgid "Internal Speaker"
 msgstr "内建喇叭"
 
+#: ../py/test/pytests/audio_basic.py
+msgid ""
+"Press 'P' to first play a sample for each channel to ensure audio output "
+"works.<br>Press 'R' to record {record_sec} seconds, Playback will "
+"follow<br>Press space to mark pass"
+msgstr ""
+"按 'P' 键播放范例<br>按 'R' 键开始录音{record_sec}秒,之后会重播录到的声音"
+"<br>压下空白表示成功"
+
+#: ../py/test/pytests/audio_basic.py
+msgid "Start recording"
+msgstr "开始录音"
+
+#: ../py/test/pytests/audio_basic.py
+msgid "Playback sound (Mic channel {channel})"
+msgstr "重播录到的声音(麦克风通道{channel})"
+
+#: ../py/test/pytests/audio_basic.py
+msgid "Playback sound to channel {channel}"
+msgstr "播放范例到通道{channel})"
+
+#: ../py/test/pytests/audio_basic.py
+msgid "Headset"
+msgstr "外接耳机"
+
+#: ../py/test/pytests/audio_loop/audio_loop.py
+msgid "Plug in audio jack dongle"
+msgstr "请放入音源孔测试置具"
+
+#: ../py/test/pytests/audio_loop/audio_loop.py
+msgid "Hit s to start loopback test"
+msgstr "请按下s键开始音源回放测试"
+
+#: ../py/test/pytests/audio_quality.py
+msgid "Press 'Space' to start test"
+msgstr "按空白键开始测试"
+
+#: ../py/test/pytests/audio_quality.py
+msgid "Connected"
+msgstr "已连线"
+
+#: ../py/test/pytests/audio_quality.py
+msgid "Waiting for command"
+msgstr "等待指令中"
+
+#: ../py/test/pytests/audio_quality.py
+msgid "Audio looping"
+msgstr "音源回放中"
+
+#: ../py/test/pytests/audio_quality.py
+msgid "Speaker on"
+msgstr "喇叭开启"
+
+#: ../py/test/pytests/audio_quality.py
+msgid "LCD Dmic on"
+msgstr "LCD mic开启"
+
+#: ../py/test/pytests/audio_quality.py
+msgid "MLB Dmic on"
+msgstr "MLB mic开启"
+
+#: ../py/test/pytests/audio_quality.py
+msgid "Playing tone to left channel"
+msgstr "播音至左声道"
+
+#: ../py/test/pytests/audio_quality.py
+msgid "Playing tone to right channel"
+msgstr "播音至右声道"
+
+#: ../py/test/pytests/audio_quality.py
+msgid "Waiting for IP address"
+msgstr "等待 IP 设定"
+
+#: ../py/test/pytests/audio_quality.py
+msgid "Connecting to ShopFloor..."
+msgstr "连接到 ShopFloor 中..."
+
+#: ../py/test/pytests/audio_quality.py
+msgid "Downloading parameters"
+msgstr "下载测试规格中"
+
+#: ../py/test/pytests/audio_quality.py
+msgid "Remove Ethernet connectivity"
+msgstr "移除网路介面卡"
+
+#: ../py/test/pytests/audio_quality.py
+msgid "Waiting for Ethernet connectivity to audio fixture"
+msgstr "等待网路介面卡连接到 audio 置具"
+
+#: ../py/test/pytests/audio_quality.py
+msgid "Ready for connection"
+msgstr "准备完成,等待链接"
+
+#: ../py/test/pytests/audio_quality.py
+msgid "Upload log"
+msgstr "上传记录档"
+
+#: ../py/test/pytests/bad_blocks.py
+msgid "Testing {test_size_mb} region of storage"
+msgstr "正在测试 {test_size_mb} 的 存储 空间"
+
+#: ../py/test/pytests/bad_blocks.py
+msgid "Phase {current_phase}/{total_phases}: "
+msgstr "阶段 {current_phase}/{total_phases}: "
+
+#: ../py/test/pytests/barcode_scan_to_file.py ../py/test/pytests/scan/scan.py
+#: ../py/test/pytests/vpd_from_http.py
+msgid "The scanned value is empty."
+msgstr "扫描编号是空的。"
+
+#: ../py/test/pytests/barcode_scan_to_file.py
+msgid "The scanned value \"{scan_value}\" does not match the expected format."
+msgstr "所扫描的编号「{scan_value}」格式不对。"
+
+#: ../py/test/pytests/barcode_scan_to_file.py ../py/test/pytests/scan/scan.py
+msgid "Scan {label}"
+msgstr "扫描{label}"
+
+#: ../py/test/pytests/barcode_scan_to_file.py ../py/test/pytests/scan/scan.py
+msgid "Please scan the {label} and press ENTER."
+msgstr "请扫描{label}后按下 ENTER。"
+
+#: ../py/test/pytests/battery_current.py
+msgid "Battery Current Test"
+msgstr "充电放电电流测试"
+
+#: ../py/test/pytests/battery_current.py
+msgid ""
+"Waiting for {target_status} current to meet {target_current} mA. (Currently "
+"{status} at {current} mA)"
+msgstr ""
+"等待{target_status}电流大于 {target_current} mA. (目前{status}中:{current} "
+"mA)"
+
+#: ../py/test/pytests/battery_current.py
+msgid "charging"
+msgstr "充电"
+
+#: ../py/test/pytests/battery_current.py
+msgid "discharging"
+msgstr "放电"
+
+#: ../py/test/pytests/battery_current.py
+msgid "Insert power to {prompt}({voltage}mV)"
+msgstr "请将电源线插入{prompt}({voltage}mV)"
+
+#: ../py/test/pytests/blocking_charge.py ../py/test/pytests/charger.py
+msgid "Charging"
+msgstr "充电"
+
+#: ../py/test/pytests/blocking_charge.py
+msgid ""
+"Charging to {target}% (Start: {start}%. Current: {current}%.)<br>Time "
+"elapsed: {elapsed}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Time "
+"remaining: {remaining}"
+msgstr ""
+"充电至 {target}% (起始电量: {start}%. 当前电量: {current}%.)<br>经过时间: "
+"{elapsed}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;剩余时间: "
+"{remaining}"
+
+#: ../py/test/pytests/bluetooth.py
+msgid "Bluetooth functional Test"
+msgstr "蓝牙功能测试"
+
+#: ../py/test/pytests/bluetooth.py
+msgid "Detect bluetooth adapter"
+msgstr "检测蓝牙适配器"
+
+#: ../py/test/pytests/bluetooth.py
+msgid "Enable the connection ability of bluetooth device and press Enter"
+msgstr "启用蓝牙装置的连接功能然后按输入键"
+
+#: ../py/test/pytests/bluetooth.py
+msgid ""
+"Place the base into the fixture, and press the space key on the test host."
+msgstr "请把测试键盘放入测试机具中,然后按下电脑的 space 键'"
+
+#: ../py/test/pytests/bluetooth.py
+msgid "Please re-attach the magnet, and press the space key on the test host."
+msgstr "请重新连结磁铁,然后按下电脑的 space 键'"
+
+#: ../py/test/pytests/bluetooth.py
+msgid ""
+"Turn on charging by pressing the green button, take the keyboard out and put "
+"it back, and press the space key on the test host."
+msgstr "请按下绿色键开始充电, 然后取出再放回键盘, 最后按下电脑的 space 键"
+
+#: ../py/test/pytests/bluetooth.py
+msgid "Read battery level for the 1st time."
+msgstr "第1次读取电池电量"
+
+#: ../py/test/pytests/bluetooth.py
+msgid "Read battery level for the 2nd time."
+msgstr "第2次读取电池电量"
+
+#: ../py/test/pytests/bluetooth.py
+msgid "Check if the battery has charged to a higher percentage"
+msgstr "检查充电之后电量是否增加"
+
+#: ../py/test/pytests/bluetooth.py
+msgid "Check battery level."
+msgstr "检查电池电量"
+
+#: ../py/test/pytests/bluetooth.py
+msgid ""
+"Press the green button again to stop charging, and press the space key on "
+"the test host."
+msgstr "请按下绿色键以停止充电,然后按下电脑的 space 键"
+
+#: ../py/test/pytests/bluetooth.py
+msgid ""
+"Take the base out of the fixture, and press the space key on the test host."
+msgstr "请把测试键盘取出,然后按下电脑的 space 键"
+
+#: ../py/test/pytests/bluetooth.py
+msgid "Read firmware revision string."
+msgstr "读取键盘韧体版本"
+
+#: ../py/test/pytests/bluetooth.py
+msgid "Scanning..."
+msgstr "扫描中..."
+
+#: ../py/test/pytests/bluetooth.py
+msgid "Detect RSSI (count {count}/{total})"
+msgstr "侦测RSSI (第 {count}/{total} 次)"
+
+#: ../py/test/pytests/bluetooth.py
+msgid "Enable the connection ability of input bluetooth device and press Enter"
+msgstr "启用蓝牙输入装置的连接功能然后按输入键"
+
+#: ../py/test/pytests/bluetooth.py
+msgid "Pairing to input device now..."
+msgstr "配对到蓝牙输入设备..."
+
+#: ../py/test/pytests/bluetooth.py
+msgid "Press shift-p-a-i-r simultaneously on the base."
+msgstr "请在在测试键盘上同时按住 shift-p-a-i-r"
+
+#: ../py/test/pytests/bluetooth.py
+msgid "Connecting to input device now..."
+msgstr "连接到蓝牙输入设备..."
+
+#: ../py/test/pytests/bluetooth.py
+msgid "Please test input. Press Escape to fail and Enter to pass"
+msgstr "请测试输入, 如果失败, 请按Esc键,如果成功,请按Enter键"
+
+#: ../py/test/pytests/bluetooth.py
+msgid "Unpairing"
+msgstr "取消配对"
+
+#: ../py/test/pytests/bluetooth.py
+msgid "Authentication failed, retrying..."
+msgstr "验证失败,重试"
+
+#: ../py/test/pytests/bluetooth.py
+msgid "Enter passkey {key} then press enter on the base."
+msgstr "按 {key} 再按回车"
+
 #: ../py/test/pytests/brightness/brightness.py
 msgid "<br>Press ENTER to pass, or ESC to fail."
 msgstr "<br>测试正常请按 ENTER ,不正常请按 ESC"
 
-#: ../py/test/pytests/brightness/brightness.py
+#: ../py/test/pytests/brightness/brightness.py ../py/test/pytests/camera.py
+#: ../py/test/pytests/webrtc_camera.py
 msgid "Time remaining: {time}"
 msgstr "剩余时间:{time}"
 
@@ -64,6 +403,18 @@
 msgid "Please check if backlight brightness is changing from dark to bright."
 msgstr "请检查萤幕亮度是否由暗变亮"
 
+#: ../py/test/pytests/button.py
+msgid "Press the {name} button"
+msgstr "按下{name}按钮"
+
+#: ../py/test/pytests/button.py
+msgid "Press the {name} button ({count}/{total})"
+msgstr "按下{name}按钮 ({count}/{total})"
+
+#: ../py/test/pytests/button.py
+msgid "Release the button"
+msgstr "松开按钮"
+
 #: ../py/test/pytests/buzzer.py
 msgid "How many beeps do you hear? <br>Press space to start."
 msgstr "你听到几声哔声?<br>压下空白键开始测试"
@@ -74,6 +425,504 @@
 "<br>Press 'r' to play again."
 msgstr "你听到几声哔声?<br>请按下数字代表你听到几声哔声<br>按下 'r' 重播"
 
+#: ../py/test/pytests/call_shopfloor.py ../py/test/pytests/memory_size.py
+msgid "Shop floor exception:"
+msgstr "Shop floor 错误:"
+
+#: ../py/test/pytests/call_shopfloor.py ../py/test/pytests/memory_size.py
+msgid "Retry"
+msgstr "重试"
+
+#: ../py/test/pytests/camera.py
+msgid "Capturing image..."
+msgstr "拍照中..."
+
+#: ../py/test/pytests/camera.py
+msgid "Press ENTER to pass or ESC to fail."
+msgstr "摄像头运作正常请按 ENTER,不正常请按 ESC"
+
+#: ../py/test/pytests/camera.py
+msgid "Running the camera until timeout."
+msgstr "运行相机直到超时"
+
+#: ../py/test/pytests/camera.py
+msgid "Running the camera until expected number of frames captured."
+msgstr "运行相机直到给订数量"
+
+#: ../py/test/pytests/camera.py
+msgid "Scanning QR code..."
+msgstr "侦测 QR 码中..."
+
+#: ../py/test/pytests/camera.py
+msgid "Scanned QR code: \"{text}\""
+msgstr "已侦测 QR 码: \"{text}\""
+
+#: ../py/test/pytests/camera.py
+msgid "Detecting faces..."
+msgstr "侦测人脸中..."
+
+#: ../py/test/pytests/camera.py
+msgid ""
+"Press 0 if LED is flickering, 1 if LED is constantly lit,<br>or ESC to fail."
+msgstr "LED 闪烁请按 0,一直亮着请按 1,没亮请按 ESC"
+
+#: ../py/test/pytests/camera_fixture.py
+msgid "Camera Fixture Calibration"
+msgstr "相机制具校正"
+
+#: ../py/test/pytests/camera_fixture.py
+msgid "Camera Lens Shading Test"
+msgstr "相机镜头黑点测试"
+
+#: ../py/test/pytests/camera_fixture.py
+msgid "Camera Image Quality Test"
+msgstr "相机影像品质测试"
+
+#: ../py/test/pytests/camera_fixture.py
+msgid "ALS Sensor Calibration"
+msgstr "光感应器校正"
+
+#: ../py/test/pytests/camera_fixture.py
+msgid "Starting the test"
+msgstr "开始测试"
+
+#: ../py/test/pytests/camera_fixture.py
+msgid "Reading serial number"
+msgstr "读取序号"
+
+#: ../py/test/pytests/camera_fixture.py
+msgid "Checking firmware version"
+msgstr "检查韧体版本"
+
+#: ../py/test/pytests/camera_fixture.py
+msgid "Initializing camera"
+msgstr "初始化摄像头"
+
+#: ../py/test/pytests/camera_fixture.py
+msgid "Adjusting white balance"
+msgstr "白平衡调试"
+
+#: ../py/test/pytests/camera_fixture.py
+msgid "Reading test image"
+msgstr "读取测试影像"
+
+#: ../py/test/pytests/camera_fixture.py
+msgid "Reading Light1 ALS value"
+msgstr "读取灯光1 ALS数值"
+
+#: ../py/test/pytests/camera_fixture.py
+msgid "Reading Light2 ALS value"
+msgstr "读取灯光2 ALS数值"
+
+#: ../py/test/pytests/camera_fixture.py
+msgid "Reading Light3 ALS value"
+msgstr "读取灯光3 ALS数值"
+
+#: ../py/test/pytests/camera_fixture.py
+msgid "Locating test pattern"
+msgstr "定位测试图样"
+
+#: ../py/test/pytests/camera_fixture.py
+msgid "Checking vignetting level"
+msgstr "检测影像暗角"
+
+#: ../py/test/pytests/camera_fixture.py
+msgid "Calculate the ALS line"
+msgstr "计算ALS结果"
+
+#: ../py/test/pytests/camera_fixture.py
+msgid "Writing the ALS calibration data to vpd"
+msgstr "写入ALS校正结果"
+
+#: ../py/test/pytests/camera_fixture.py
+msgid "Checking image sharpness"
+msgstr "检测影像清晰度"
+
+#: ../py/test/pytests/camera_fixture.py
+msgid "All tests are complete"
+msgstr "测试已全部完成"
+
+#: ../py/test/pytests/camera_fixture.py
+msgid "Test data saved"
+msgstr "记录档已写入"
+
+#: ../py/test/pytests/cellular_switch_firmware.py
+msgid "Switching firmware to {target!r}<br>"
+msgstr "切换数据机至{target!r}韧体"
+
+#: ../py/test/pytests/chameleon/chameleon.py
+msgid "Automated External Display Test"
+msgstr "自动外接显示测试"
+
+#: ../py/test/pytests/chameleon/chameleon.py
+msgid "Please plug in the display to test"
+msgstr "请拔下耳机"
+
+#: ../py/test/pytests/chameleon/chameleon.py
+msgid ""
+"Testing DUT {dut_port} port on Chameleon {chameleon_port} port using mode "
+"{mode}..."
+msgstr ""
+"测试 DUT {dut_port} 对 Chameleon {chameleon_port} 外接显示 mode: {mode}..."
+
+#: ../py/test/pytests/chameleon/chameleon.py
+msgid "Automated testing on {dut_port} to {chameleon_port} in progress..."
+msgstr "{dut_port} 对 {chameleon_port} 自动测试进行中..."
+
+#: ../py/test/pytests/chameleon/chameleon.py
+msgid "Captured images mismatch"
+msgstr "撷取的图片不相符"
+
+#: ../py/test/pytests/charger.py
+msgid "Charger Test"
+msgstr "充电放电测试"
+
+#: ../py/test/pytests/charger.py
+msgid "Discharging"
+msgstr "放电"
+
+#: ../py/test/pytests/charger.py
+msgid ""
+"{action} to {target:.2f}{unit} (Current charge: {charge:.2f}{unit}, battery "
+"current: {battery_current} mA) under load {load}.<br>Time remaining: "
+"{timeout} sec."
+msgstr ""
+"{action} 至 {target:.2f}{unit} (目前电量为 {charge:.2f}{unit}, 电池电流 "
+"{battery_current} mA)负载 {load}.<br>剩馀时间: {timeout} 秒."
+
+#: ../py/test/pytests/charger.py
+msgid "OK! Meet {target:.2f}{unit}"
+msgstr "OK! 达到 {target:.2f}{unit}"
+
+#: ../py/test/pytests/charger.py
+msgid "Testing charger"
+msgstr "测试充电中"
+
+#: ../py/test/pytests/charger.py
+msgid "Testing discharge"
+msgstr "测试放电中"
+
+#: ../py/test/pytests/check_image_version.py
+msgid "Check Image Version"
+msgstr "检查映像版本"
+
+#: ../py/test/pytests/check_image_version.py
+msgid "Factory image version is incorrect. Please re-image this device."
+msgstr "映像版本不正确,请重新安装。"
+
+#: ../py/test/pytests/check_image_version.py
+msgid "Please connect to ethernet."
+msgstr "请连接到以太网。"
+
+#: ../py/test/pytests/check_image_version.py
+msgid "Factory image version is incorrect. Press space to re-image."
+msgstr "映像版本不正确,请按空白键重新安装。"
+
+#: ../py/test/pytests/check_image_version.py
+msgid "Flashing netboot firmware..."
+msgstr "烧录网路开机固件..."
+
+#: ../py/test/pytests/check_image_version.py
+msgid "Error flashing netboot firmware!"
+msgstr "烧录网路开机固件失败"
+
+#: ../py/test/pytests/check_wifi_calibration.py
+msgid "Calibration data doesn't meet requirement"
+msgstr ""
+
+#: ../py/test/pytests/compass.py ../py/test/pytests/tablet_mode_ui.py
+msgid "Success!"
+msgstr "成功!"
+
+#: ../py/test/pytests/compass.py
+msgid "north"
+msgstr "北"
+
+#: ../py/test/pytests/compass.py
+msgid "south"
+msgstr "南"
+
+#: ../py/test/pytests/compass.py
+msgid "Put the DUT towards {direction}"
+msgstr "将机器朝向{direction}方"
+
+#: ../py/test/pytests/countdown.py
+msgid "Elapsed time:"
+msgstr "经过时间:"
+
+#: ../py/test/pytests/countdown.py
+msgid "Remaining time:"
+msgstr "剩余时间:"
+
+#: ../py/test/pytests/countdown.py
+msgid "Load:"
+msgstr "系统负载:"
+
+#: ../py/test/pytests/countdown.py ../py/test/pytests/wifi_rf.py
+msgid "Countdown"
+msgstr "倒计时"
+
+#: ../py/test/pytests/developer_switch.py
+msgid "Please turn <b class=\"on\">ON</b> Developer Switch."
+msgstr "请<b class=\"on\">开启</b> DEV SW 开发者开关。"
+
+#: ../py/test/pytests/developer_switch.py
+msgid "Please turn <b class=\"off\">OFF</b> Developer Switch."
+msgstr "请<b class=\"off\">关闭</b> DEV SW 开发者开关。"
+
+#: ../py/test/pytests/developer_switch.py
+msgid "Develop switch is currently <b class=\"on\">ON</b>."
+msgstr "DEV SW 开发者开关目前为<b class=\"on\">开启</b>状态"
+
+#: ../py/test/pytests/developer_switch.py
+msgid "Develop switch is currently <b class=\"off\">OFF</b>."
+msgstr "DEV SW 开发者开关目前为<b class=\"off\">关闭</b>状态"
+
+#: ../py/test/pytests/display_images.py
+msgid ""
+"Press space to show each image on display<br>Press Enter to PASS after "
+"showing all images"
+msgstr "按空白键来拨放影像在萤幕上<br>拨放完所有影像后,压下Enter表示成功"
+
+#: ../py/test/pytests/display_images.py
+msgid "({index}/{total})Uploading images {name}"
+msgstr "({index}/{total})正在上传图档 {name}"
+
+#: ../py/test/pytests/display_images.py
+msgid "Display Test"
+msgstr "显示测试"
+
+#: ../py/test/pytests/emmc_check_fw_version.py
+msgid "eMMC Firmware Version Incorrect"
+msgstr "eMMC 韧体版本不对"
+
+#: ../py/test/pytests/emmc_check_fw_version.py
+msgid ""
+"The eMMC firmware version ({version}) is incorrect. <br>Please run the eMMC "
+"firmware update tool."
+msgstr ""
+"eMMC 韧体版({version})版本不对。<br>必须更新 eMMC 韧体并重新安装工厂测试软"
+"件。"
+
+#: ../py/test/pytests/ethernet.py
+msgid ""
+"Please plug ethernet cable into built-in ethernet port<br>Press space to "
+"start."
+msgstr "请插入网路线到内建网路埠<br>压下空白键开始测试"
+
+#: ../py/test/pytests/ext_display/ext_display.py
+msgid "External Display Test"
+msgstr "外接显示屏测试"
+
+#: ../py/test/pytests/ext_display/ext_display.py
+msgid "{display} Connect"
+msgstr "{display} 连接"
+
+#: ../py/test/pytests/ext_display/ext_display.py
+msgid "{display} Video"
+msgstr "{display} 视讯"
+
+#: ../py/test/pytests/ext_display/ext_display.py
+msgid "{display} Disconnect"
+msgstr "{display} 移除"
+
+#: ../py/test/pytests/ext_display/ext_display.py
+msgid "Connect external display: {display}"
+msgstr "请接上外接显示屏: {display}"
+
+#: ../py/test/pytests/ext_display/ext_display.py
+msgid "Do you see video on {display}?"
+msgstr "外接显示屏 {display} 是否有画面?"
+
+#: ../py/test/pytests/ext_display/ext_display.py
+msgid "Fixture is checking if video is displayed on {display}?"
+msgstr "治具正在测试外接显示屏 {display} 是否有画面?"
+
+#: ../py/test/pytests/ext_display/ext_display.py
+msgid "Disconnect external display: {display}"
+msgstr "移除外接显示屏: {display}"
+
+#: ../py/test/pytests/ext_display/ext_display.py
+msgid "Press <span id=\"pass_key\">{key}</span> to pass the test."
+msgstr "通过请按 <span id=\"pass_key\">{key}</span> 键"
+
+#: ../py/test/pytests/ext_display/ext_display.py
+msgid "{display_label} Audio"
+msgstr " {display_label} 音讯"
+
+#: ../py/test/pytests/fan_speed.py
+msgid "Fan Speed Test"
+msgstr "风扇转速测试"
+
+#: ../py/test/pytests/fan_speed.py
+msgid "Fan speed (RPM):"
+msgstr "风扇转速(RPM):"
+
+#: ../py/test/pytests/fan_speed.py
+msgid "Spin up fan speed: {observed_rpm} -> {target_rpm} RPM."
+msgstr "风扇加速: {observed_rpm} -> {target_rpm} RPM."
+
+#: ../py/test/pytests/fan_speed.py
+msgid "Spin down fan speed: {observed_rpm} -> {target_rpm} RPM."
+msgstr "风扇减速: {observed_rpm} -> {target_rpm} RPM."
+
+#: ../py/test/pytests/fastboot_flash.py
+msgid "Switching device into fastboot."
+msgstr "等待待测物进入fastboot"
+
+#: ../py/test/pytests/fastboot_flash.py
+msgid "Switching device back to normal mode."
+msgstr "等待待测物正常开机"
+
+#: ../py/test/pytests/fastboot_flash.py
+msgid "Flashing {file} to {partition}."
+msgstr "安装 {file} 至 {partition}."
+
+#: ../py/test/pytests/finalize/finalize.py
+msgid "Checking system status for finalization..."
+msgstr "正在检查系统是否已可执行最终程序..."
+
+#: ../py/test/pytests/finalize/finalize.py
+msgid "System is not ready.<br>Please fix RED tasks and then press SPACE."
+msgstr "系统尚未就绪。<br>请修正红色项目后按空白键重新检查。"
+
+#: ../py/test/pytests/finalize/finalize.py
+msgid "System is NOT ready. Please fix RED tasks."
+msgstr "系统尚未就绪。请修正红色项目。"
+
+#: ../py/test/pytests/finalize/finalize.py
+msgid "Press \"f\" to force starting finalization procedure."
+msgstr "按下 「f」 键以强迫开始最终程序。"
+
+#: ../py/test/pytests/finalize/finalize.py
+msgid "System is READY. Press SPACE to start FINALIZATION."
+msgstr "系统已准备就绪。 请按空白键开始最终程序!"
+
+#: ../py/test/pytests/finalize/finalize.py
+msgid ""
+"Finalizing, please wait.<br>Do not restart the device or terminate this test,"
+"<br>or the device may become unusable."
+msgstr ""
+"正在开始最终程序,请稍等.<br>不要重启机器或停止测试,<br>不然机器将无法开机。"
+
+#: ../py/test/pytests/finalize/finalize.py
+msgid "Verify all tests passed"
+msgstr "确认测试项目都已成功了"
+
+#: ../py/test/pytests/finalize/finalize.py
+msgid "Turn off Developer Switch"
+msgstr "停用开发者开关(DevSwitch)"
+
+#: ../py/test/pytests/finalize/finalize.py
+msgid "Enable write protection pin"
+msgstr "确认硬体写入保护已开启"
+
+#: ../py/test/pytests/finalize_accessory.py
+msgid "Get the final test result..."
+msgstr "检查系统最终测试结果..."
+
+#: ../py/test/pytests/flash_netboot.py
+msgid "Flash Netboot Firmware"
+msgstr "烧录 netboot 韧体"
+
+#: ../py/test/pytests/flush_event_logs.py ../py/test/pytests/sync_shopfloor.py
+msgid "Contacting shopfloor server..."
+msgstr "正在与shopfloor server连线..."
+
+#: ../py/test/pytests/flush_event_logs.py ../py/test/pytests/sync_shopfloor.py
+msgid "A software update is available. Press SPACE to update."
+msgstr "有可用的更新。按空白键更新。"
+
+#: ../py/test/pytests/flush_event_logs.py ../py/test/pytests/sync_shopfloor.py
+msgid ""
+"Unable to contact shopfloor server. Will try again in {time_left} seconds."
+msgstr "无法连线到 shopfloor server。将于 {time_left} 秒后自动重试。"
+
+#: ../py/test/pytests/flush_testlog.py
+msgid "Attempting to flush logs upstream..."
+msgstr "同步测试记录..."
+
+#: ../py/test/pytests/flush_testlog.py
+msgid "Unable to flush logs. Will try again in {secs} seconds."
+msgstr "无法同步测试记录,将于 {secs} 秒后自动重试。"
+
+#: ../py/test/pytests/gyroscope.py
+msgid "Please do not move the device."
+msgstr "请勿移动待测物。"
+
+#: ../py/test/pytests/gyroscope.py
+msgid "Please rotate the device."
+msgstr "请转动待测物。"
+
+#: ../py/test/pytests/gyroscope.py
+msgid ""
+"Calibration will be started within {secs} seconds.Please do not move device."
+msgstr "测试程序即将于 {secs} 秒后开始,请勿移动待测物。"
+
+#: ../py/test/pytests/hwid.py
+msgid "Fetching HWID from shop floor server..."
+msgstr "从 Shop Floor 服务器抓取 HWID 中..."
+
+#: ../py/test/pytests/hwid.py
+msgid "Auto probing HWID..."
+msgstr "自动侦测 HWID 中..."
+
+#: ../py/test/pytests/hwid.py
+msgid "Writing HWID: {hwid}"
+msgstr "写入 HWID: {hwid}"
+
+#: ../py/test/pytests/hwid.py
+msgid "Select HWID:<br><br>"
+msgstr "选择 HWID:<br><br>"
+
+#: ../py/test/pytests/hwid.py
+msgid "<br><br>Select with Enter key"
+msgstr "<br><br>使用 Enter 键选择"
+
+#: ../py/test/pytests/hwid.py
+msgid "Cannot find matched HWID."
+msgstr "无法找到匹配的 HWID。"
+
+#: ../py/test/pytests/hwid.py
+msgid "HWID Test"
+msgstr "HWID测试"
+
+#: ../py/test/pytests/hwid_v3.py
+msgid "Probing components..."
+msgstr "正在探索零件..."
+
+#: ../py/test/pytests/hwid_v3.py
+msgid "Generating HWID (v3)..."
+msgstr "正在产生 HWID (v3)..."
+
+#: ../py/test/pytests/hwid_v3.py
+msgid "Verifying HWID (v3): {encoded_string}..."
+msgstr "正在验证 HWID (v3): {encoded_string}..."
+
+#: ../py/test/pytests/hwid_v3.py
+msgid "(unchanged)"
+msgstr "(不变)"
+
+#: ../py/test/pytests/hwid_v3.py
+msgid "Setting HWID (v3): {encoded_string}..."
+msgstr "正在写入 HWID (v3): {encoded_string}..."
+
+#: ../py/test/pytests/keyboard_backlight.py
+msgid "Keyboard Backlight Test"
+msgstr "键盘背光测试"
+
+#: ../py/test/pytests/keyboard_backlight.py
+msgid "If the keyboard backlight lights up, press ENTER. "
+msgstr "檢查鍵盤背光是否亮起,是請按ENTER。"
+
+#: ../py/test/pytests/keyboard_backlight.py
+msgid "If the keyboard backlight is off, press ENTER. "
+msgstr "檢查鍵盤背光是否熄滅,是請按ENTER。"
+
+#: ../py/test/pytests/keyboard_smt.py
+msgid "Expected keycode sequence:"
+msgstr "目标键序:"
+
 #: ../py/test/pytests/led/led.py
 msgid "LED Test"
 msgstr "LED 测试"
@@ -142,12 +991,28 @@
 
 #: ../py/test/pytests/led/led.py
 msgid ""
-"<span class=\"sub-title\">Test {test_id}</span><br />Please press number key "
+"<span class=\"sub-title\">Test {test_id}</span><br>Please press number key "
 "according to the <strong>{name}</strong> color"
 msgstr ""
-"<span class=\"sub-title\">测试 {test_id}</span><br />请根据 <strong>{name}</"
+"<span class=\"sub-title\">测试 {test_id}</span><br>请根据 <strong>{name}</"
 "strong> 的颜色按下数字键"
 
+#: ../py/test/pytests/lid_switch/lid_switch.py
+msgid "Close then open the lid"
+msgstr "关上接着打开上盖"
+
+#: ../py/test/pytests/lid_switch/lid_switch.py
+msgid "Open the lid"
+msgstr "请打开上盖"
+
+#: ../py/test/pytests/lid_switch/lid_switch.py
+msgid "Magnetizing lid sensor"
+msgstr "磁化上盖感应器"
+
+#: ../py/test/pytests/lid_switch/lid_switch.py
+msgid "Demagnetizing lid sensor"
+msgstr "消磁化上盖感应器"
+
 #: ../py/test/pytests/lightbar.py
 msgid "Lightbar Test"
 msgstr "光棒测试"
@@ -160,6 +1025,10 @@
 msgid "dark"
 msgstr "全暗"
 
+#: ../py/test/pytests/memory_size.py
+msgid "Checking memory info..."
+msgstr "正在检查内存大小..."
+
 #: ../py/test/pytests/message/message.py
 msgid ""
 "<div>Press <strong>Enter</strong> to continue, or <strong>ESC</strong> if "
@@ -175,10 +1044,648 @@
 msgid "Message"
 msgstr "讯息"
 
+#: ../py/test/pytests/network_setup/network_setup.py
+msgid "Setup network connection"
+msgstr "设定网络连线"
+
+#: ../py/test/pytests/network_setup/network_setup.py
+msgid "Setting up interface {interface}"
+msgstr "正在设定网络介面 {interface}"
+
+#: ../py/test/pytests/network_setup/network_setup.py
+msgid "Press space to continue"
+msgstr "请按空白键继续"
+
+#: ../py/test/pytests/network_setup/network_setup.py
+msgid "No physical link on {interface}"
+msgstr "{interface} 没有连接网络线"
+
+#: ../py/test/pytests/network_setup/network_setup.py
+msgid "Interface {interface} not found"
+msgstr "找不到网络介面 {interface}"
+
+#: ../py/test/pytests/network_setup/network_setup.py
+msgid "Interface {interface} not initialized"
+msgstr "网络介面 {interface} 未成功初始化"
+
 #: ../py/test/pytests/ping_test.py
 msgid "Ping test"
 msgstr "连线测试"
 
+#: ../py/test/pytests/pointing_device.py
+msgid "Non-touchpad Pointing Device Test"
+msgstr "非触控板之指向装置测试"
+
+#: ../py/test/pytests/pointing_device.py
+msgid "Please move the pointer over four quarters."
+msgstr "请移动鼠标至此文字四周"
+
+#: ../py/test/pytests/pointing_device.py
+msgid "Move Here!"
+msgstr "移动鼠标至此"
+
+#: ../py/test/pytests/pointing_device.py
+msgid "Please click the pointing device."
+msgstr "请按下指向装置左键"
+
+#: ../py/test/pytests/pointing_device.py
+msgid "Please right-click the pointing device."
+msgstr "请按下指向装置右键"
+
+#: ../py/test/pytests/pointing_device.py
+msgid "Please scroll up with the pointing device."
+msgstr "请用指向装置向上卷动"
+
+#: ../py/test/pytests/pointing_device.py
+msgid "Please scroll down with the pointing device."
+msgstr "请用指向装置向下卷动"
+
+#: ../py/test/pytests/power_under_stress.py
+msgid "Voltage: {voltage} mV"
+msgstr "电压: {voltage} mV"
+
+#: ../py/test/pytests/power_under_stress.py
+msgid "Current: {current} mA"
+msgstr "电流: {current} mA"
+
+#: ../py/test/pytests/power_under_stress.py
+msgid "Count Down: {secs} s"
+msgstr "倒数 {secs} 秒"
+
+#: ../py/test/pytests/probe/probe.py
+msgid "Press SPACE to continue"
+msgstr "按空白键继续"
+
+#: ../py/test/pytests/probe_sim.py
+msgid "SIM Card Test"
+msgstr "SIM卡测试"
+
+#: ../py/test/pytests/probe_sim.py
+msgid "Please insert the SIM card"
+msgstr "请插入SIM卡"
+
+#: ../py/test/pytests/probe_sim.py
+msgid "Detected! Please remove the SIM card"
+msgstr "已经侦测SIM卡, 请移除SIM卡"
+
+#: ../py/test/pytests/probe_sim.py
+msgid "Checking SIM card is present or not..."
+msgstr "检查SIM卡是否存在"
+
+#: ../py/test/pytests/probe_sim_card_tray.py
+msgid "SIM Card Tray Test"
+msgstr "SIM卡卡盘测试"
+
+#: ../py/test/pytests/probe_sim_card_tray.py
+msgid "Please insert the SIM card tray"
+msgstr "请插入SIM卡卡盘"
+
+#: ../py/test/pytests/probe_sim_card_tray.py
+msgid "Detected! Please remove the SIM card tray"
+msgstr "已经侦测SIM卡卡盘, 请移除SIM卡卡盘"
+
+#: ../py/test/pytests/raiden_cc2_pull_test.py
+msgid "Raiden CC2 pull test"
+msgstr "Raiden CC2 电压测试"
+
+#: ../py/test/pytests/raiden_cc2_pull_test.py
+msgid "Raiden port is disconnected in {secs:.1f} seconds"
+msgstr "Raiden port 失去连接 {secs:.1f} 秒"
+
+#: ../py/test/pytests/raiden_cc2_pull_test.py
+msgid "Please remove Raiden cable in {secs:.1f} seconds"
+msgstr "请在 {secs:.1f} 秒内移除 Raiden 线"
+
+#: ../py/test/pytests/raiden_cc2_pull_test.py
+msgid "Please attach Raiden cable in {secs:.1f} seconds"
+msgstr "请在 {secs:.1f} 秒内连接 Raiden 线"
+
+#: ../py/test/pytests/raiden_cc_flip_check.py
+msgid "Raiden CC Detect"
+msgstr "Raiden CC 检查"
+
+#: ../py/test/pytests/raiden_cc_flip_check.py
+msgid "Flip Raiden cable and plug in again..."
+msgstr "将 Raiden port 头反转后再次插入机器..."
+
+#: ../py/test/pytests/raiden_cc_flip_check.py
+msgid "And press Enter key to continue..."
+msgstr "并按 Enter 键继续..."
+
+#: ../py/test/pytests/raiden_cc_flip_check.py
+msgid "Wait DUT to reconnect"
+msgstr "等待 DUT 重新连接"
+
+#: ../py/test/pytests/raiden_charge.py
+msgid "Raiden Charging Test"
+msgstr "Raiden 充电测试"
+
+#: ../py/test/pytests/raiden_charge.py
+msgid "Waiting for ADB device connection..."
+msgstr "等待机器连线..."
+
+#: ../py/test/pytests/raiden_charge.py
+msgid "Checking Plankton INA current for protection..."
+msgstr "检查电流保护..."
+
+#: ../py/test/pytests/raiden_charge.py
+msgid "Testing battery {voltage}V charging..."
+msgstr "测试电池 {voltage}V 充电中..."
+
+#: ../py/test/pytests/raiden_charge.py
+msgid "Testing battery discharging..."
+msgstr "测试电池放电中..."
+
+#: ../py/test/pytests/raiden_display.py
+msgid "Raiden Display Test"
+msgstr "Raiden 显示测试"
+
+#: ../py/test/pytests/raiden_display.py
+msgid "Caution: monitor may turn black for a short time."
+msgstr "注意: 萤幕可能会有短暂黑屏"
+
+#: ../py/test/pytests/raiden_display.py
+msgid "Connecting BFT display: {device}"
+msgstr "正在连接 BFT 显示屏: {device}"
+
+#: ../py/test/pytests/raiden_display.py
+msgid "BFT display {device} is connected. Sending image..."
+msgstr "已连接 BFT 显示屏: {device}, 正在传送画面"
+
+#: ../py/test/pytests/raiden_display.py
+msgid "Disconnecting BFT display: {device}"
+msgstr "正在移除 BFT 显示屏: {device}"
+
+#: ../py/test/pytests/read_device_data_from_vpd.py
+msgid "Reading device data from {vpd_section} VPD..."
+msgstr "正在从 {vpd_secion} VPD 读机器资料..."
+
+#: ../py/test/pytests/recovery_button.py
+msgid "Hit SPACE to start test..."
+msgstr "按 \"空白键\" 开始测试..."
+
+#: ../py/test/pytests/recovery_button.py
+msgid ""
+"Please press recovery button for {secs:.1f} seconds ({remain_secs} seconds "
+"remaining)."
+msgstr "请持续按压恢复按钮 {secs:.1f} 秒 (剩余时间: {remain_secs} 秒)."
+
+#: ../py/test/pytests/removable_storage/removable_storage.py
+msgid ""
+"Insert {media} drive for read/write test... {extra}<br>WARNING: DATA ON "
+"INSERTED MEDIA WILL BE LOST!"
+msgstr ""
+"插入 {media} 存储以进行读写测试... {extra}<br>注意: 插入装置上的资料将会被清"
+"除!"
+
+#: ../py/test/pytests/removable_storage/removable_storage.py
+msgid "Remove {media} drive..."
+msgstr "提取 {media} 存储..."
+
+#: ../py/test/pytests/removable_storage/removable_storage.py
+msgid "Testing {media}..."
+msgstr "{media} 检查中..."
+
+#: ../py/test/pytests/removable_storage/removable_storage.py
+msgid "Performing r/w test on {count} {bsize}-byte random blocks...<br>"
+msgstr "执行 {count} 个 {bsize} 字节区块随机读写测试...<br>"
+
+#: ../py/test/pytests/removable_storage/removable_storage.py
+msgid "Performing sequential r/w test of {bsize} bytes...<br>"
+msgstr "执行 {bsize} 字节区块连续读写测试...<br>"
+
+#: ../py/test/pytests/removable_storage/removable_storage.py
+msgid "Toggle lock switch and insert {media} drive again..."
+msgstr "切换写保护开关并再次插入 {media} 存储..."
+
+#: ../py/test/pytests/removable_storage/removable_storage.py
+msgid "Remove {media} drive and toggle lock switch..."
+msgstr "提取 {media} 存储并关闭写保护开关..."
+
+#: ../py/test/pytests/removable_storage/removable_storage.py
+msgid "Device removed too early ({media})."
+msgstr "太早移除外部储存装置 ({media})."
+
+#: ../py/test/pytests/removable_storage/removable_storage.py
+msgid "Removable Storage Test"
+msgstr "可移除储存装置测试"
+
+#: ../py/test/pytests/rf_graphyte/rf_graphyte.py
+msgid "Fetching config files from shopfloor"
+msgstr "从 shopfloor 下载测试参数"
+
+#: ../py/test/pytests/rf_graphyte/rf_graphyte.py
+msgid "Executing Graphyte"
+msgstr "执行 Graphyte"
+
+#: ../py/test/pytests/rf_graphyte/rf_graphyte.py
+msgid "Uploading result files to shopfloor"
+msgstr "上传测试纪录到 shopfloor"
+
+#: ../py/test/pytests/robot_movement.py
+msgid "Initializing Robot..."
+msgstr "正在初始化机器手臂..."
+
+#: ../py/test/pytests/robot_movement.py
+msgid ""
+"Please load DUT onto the robot, connect all cables, and press <b>SPACE</b> "
+"to continue."
+msgstr "将DUT放上机器手臂并接上线路后按下<b>空白键</b>开始。"
+
+#: ../py/test/pytests/robot_movement.py
+msgid "Prepare for movement."
+msgstr "准备开始移动。"
+
+#: ../py/test/pytests/robot_movement.py
+msgid "Moving to start position..."
+msgstr "正在移动至起始位置。"
+
+#: ../py/test/pytests/robot_movement.py
+msgid "Moving to LOAD / UNLOAD position..."
+msgstr "正在移动至卸载位置。"
+
+#: ../py/test/pytests/robot_movement.py
+msgid "Computing..."
+msgstr "校正中..."
+
+#: ../py/test/pytests/robot_movement.py
+msgid "Pushing the result..."
+msgstr "储存结果中..."
+
+#: ../py/test/pytests/scan/scan.py
+msgid "The scanned value \"{value}\" does not match the expected format."
+msgstr "所扫描的编号「{value}」格式不对。"
+
+#: ../py/test/pytests/scan/scan.py
+msgid "The scanned value \"{value}\" is not a known {label}."
+msgstr "所扫描的编号「{value}」不是已知的{label}。"
+
+#: ../py/test/pytests/scan/scan.py
+msgid "Unable to contact shopfloor server: {exception}"
+msgstr "连不到 shopfloor server: {exception}"
+
+#: ../py/test/pytests/scan/scan.py
+msgid ""
+"The scanned value \"{value}\" does not match the expected value <span "
+"class=test-engineering-mode-only>\"{expected_value}\"</span>."
+msgstr ""
+"所扫描的编号「{value}」不搭配所期望的编号<span class=test-engineering-mode-"
+"only>「{expected_value}」</span>。"
+
+#: ../py/test/pytests/scan/scan.py ../py/test/pytests/vpd_from_http.py
+msgid "Writing to VPD. Please wait..."
+msgstr "正在写到 VPD,请稍等..."
+
+#: ../py/test/pytests/select_aux_field.py
+msgid "No selection."
+msgstr "未选择。"
+
+#: ../py/test/pytests/select_aux_field.py
+msgid "Select {label}"
+msgstr "选择{label}"
+
+#: ../py/test/pytests/select_aux_field.py
+msgid "Please select the {label} and press ENTER."
+msgstr "请选择{label}后按下 ENTER。"
+
+#: ../py/test/pytests/select_components.py
+msgid "Select Components:"
+msgstr "选择元件:"
+
+#: ../py/test/pytests/select_components.py
+msgid "Select Components"
+msgstr "选择元件"
+
+#: ../py/test/pytests/shutdown/shutdown.py
+msgid "reboot"
+msgstr "重新启动"
+
+#: ../py/test/pytests/shutdown/shutdown.py
+msgid "full reboot"
+msgstr "深度重启"
+
+#: ../py/test/pytests/shutdown/shutdown.py
+msgid "halt"
+msgstr "关机"
+
+#: ../py/test/pytests/shutdown/shutdown.py
+msgid "System is going to {operation} in {delay} seconds."
+msgstr "系统将在 {delay} 秒后{operation}."
+
+#: ../py/test/pytests/shutdown/shutdown.py
+msgid "Remote DUT is performing {operation}, timeout in {delay} seconds."
+msgstr "远端测试装置将于 {delay} 秒内{operation}."
+
+#: ../py/test/pytests/shutdown/shutdown.py
+msgid "Verifying system state after {operation}"
+msgstr "{operation}后验证系统状态"
+
+#: ../py/test/pytests/shutdown/shutdown.py
+msgid "Shutdown Test ({operation})"
+msgstr "关机测试 ({operation})"
+
+#: ../py/test/pytests/simple_battery.py
+msgid "Simple Battery Test"
+msgstr "简单电池测试"
+
+#: ../py/test/pytests/simple_battery.py
+msgid "Unplug AC to proceed"
+msgstr "拔除 AC 电源"
+
+#: ../py/test/pytests/simple_battery.py
+msgid "Plug AC to proceed"
+msgstr "插上 AC 电源"
+
+#: ../py/test/pytests/simple_battery.py
+msgid "Testing battery charge..."
+msgstr "测试电池充电中..."
+
+#: ../py/test/pytests/simple_battery.py
+msgid "Testing battery discharge..."
+msgstr "测试电池放电中..."
+
+#: ../py/test/pytests/smart_check_fw_version.py
+msgid "SSD Firmware Version Incorrect"
+msgstr "SSD 韧体版本不对"
+
+#: ../py/test/pytests/smart_check_fw_version.py
+msgid ""
+"The SSD firmware version ({fw_version}) is incorrect. <br>Please run the SSD "
+"firmware update tool."
+msgstr ""
+"SSD 韧体版({fw_version})版本不对。<br>必须更新 SSD 韧体并重新安装工厂测试软"
+"件。"
+
+#: ../py/test/pytests/spatial_sensor_calibration.py
+msgid "Accelerometer"
+msgstr "加速度计"
+
+#: ../py/test/pytests/spatial_sensor_calibration.py
+msgid "Calibrating {sensor_name}..."
+msgstr "正在校正 {sensor_name}..."
+
+#: ../py/test/pytests/spatial_sensor_calibration.py
+msgid "Device not in position"
+msgstr "装置位置不正确"
+
+#: ../py/test/pytests/spatial_sensor_calibration.py
+msgid "Please put the device in face-up position (press Enter to continue)"
+msgstr "请将装置面向上(按 Enter 继续)"
+
+#: ../py/test/pytests/spatial_sensor_calibration.py
+msgid "Waiting for device..."
+msgstr "正在等待装置..."
+
+#: ../py/test/pytests/spatial_sensor_calibration.py
+msgid "Writing calibration data..."
+msgstr "正在写入校正结果..."
+
+#: ../py/test/pytests/start/start.py
+msgid "Start Factory Test"
+msgstr "开始工厂测试"
+
+#: ../py/test/pytests/start/start.py
+msgid ""
+"Factory install process did not complete. Auto-testing stopped."
+"<br><br>Please install the factory test image using the mini-Omaha "
+"server<br>rather than booting from a USB drive.<br>"
+msgstr ""
+"安装过程中失败, 停止自动测试。<br><br>请使用完整的 mini-Omaha 伺服器安装测试"
+"程式,<br>不要直接从 USB 碟开机执行。<br>"
+
+#: ../py/test/pytests/start/start.py
+msgid "Plug in external power to continue."
+msgstr "请插上外接电源以继续。"
+
+#: ../py/test/pytests/start/start.py
+msgid "Hit SPACE to start testing..."
+msgstr "按 \"空白键\" 开始测试..."
+
+#: ../py/test/pytests/start/start.py
+msgid ""
+"No shop floor server URL. Auto-testing stopped.<br><br>Please install the "
+"factory test image using the mini-Omaha server<br>rather than booting from a "
+"USB drive.<br><br>For debugging or development, use the listed hot-keys to "
+"start<br>individual tests."
+msgstr ""
+"未指定 shop floor 服务器位址,停止自动测试。<br><br>请使用完整的 mini-Omaha "
+"服务器安装测试程式,<br>不要直接从 USB 碟开机执行。<br><br>若想除错或执行部份"
+"测试,请直接按下对应热键。"
+
+#: ../py/test/pytests/start/start.py
+msgid "Reading VPD..."
+msgstr "读取 VPD 中..."
+
+#: ../py/test/pytests/start/start.py
+msgid "Contacting shop floor server..."
+msgstr "正在和 shop floor server 联络..."
+
+#: ../py/test/pytests/start/start.py
+msgid "Initialize some shared data..."
+msgstr "重设旧有共用资料..."
+
+#: ../py/test/pytests/start/start.py
+msgid "Enter valid serial number:<br>"
+msgstr "请输入有效的序号:<br>"
+
+#: ../py/test/pytests/station_entry.py
+msgid "Start Station Test"
+msgstr "开始测试"
+
+#: ../py/test/pytests/station_entry.py
+msgid "End Station Test"
+msgstr "结束测试"
+
+#: ../py/test/pytests/station_entry.py
+msgid "Please attach DUT."
+msgstr "INSERT 请插入测试装置。"
+
+#: ../py/test/pytests/station_entry.py
+msgid "Press SPACE to start the test."
+msgstr "请按空白键开始测试。"
+
+#: ../py/test/pytests/station_entry.py
+msgid "Press SPACE to end the test."
+msgstr "请按空白键结束测试。"
+
+#: ../py/test/pytests/station_entry.py
+msgid "Sending test results to shopfloor..."
+msgstr "SENDING 传送测试结果给服务器..."
+
+#: ../py/test/pytests/station_entry.py
+msgid "Please remove DUT."
+msgstr "REMOVE 请移除测试装置。"
+
+#: ../py/test/pytests/station_entry.py
+msgid "Restarting all tests..."
+msgstr "RESTARTING 测试结束,正在重设测试列表..."
+
+#: ../py/test/pytests/stylus.py
+msgid ""
+"Please draw a line with stylus from bottom left corner to top right corner. "
+"Stay between the two red lines.<br>Press SPACE to start; Esc to fail."
+msgstr ""
+"请使用触控笔从左下方画至右上角,不要超出红线区域。<br>按空白键开始测试; Esc "
+"键标记失败"
+
+#: ../py/test/pytests/summary/summary.py
+msgid "Click or press SPACE to continue"
+msgstr "点击或按空白键继续"
+
+#: ../py/test/pytests/summary/summary.py
+msgid "Unable to proceed, since some previous tests have not passed."
+msgstr "之前所有的测试必须通过才能通过此项目"
+
+#: ../py/test/pytests/summary/summary.py
+msgid "Test Status for {test}:"
+msgstr "{test} 测试结果列表:"
+
+#: ../py/test/pytests/suspend_resume.py
+msgid "Suspend/Resume Test"
+msgstr "暂停/恢复测试"
+
+#: ../py/test/pytests/suspend_resume.py
+msgid "Suspend/Resume:"
+msgstr "暂停/恢复:"
+
+#: ../py/test/pytests/sysfs_battery.py
+msgid "Battery Self-diagnosis"
+msgstr "电池自我诊断"
+
+#: ../py/test/pytests/tablet_mode_ui.py
+msgid "Flip the lid into tablet mode"
+msgstr "把上盖掀开一圈直到贴合下盖"
+
+#: ../py/test/pytests/tablet_mode_ui.py
+msgid "Open the lid back to notebook mode"
+msgstr "把上盖掀开直到正常笔电模式"
+
+#: ../py/test/pytests/tablet_mode_ui.py
+msgid "Confirm tablet mode"
+msgstr "确认平板模式"
+
+#: ../py/test/pytests/tablet_mode_ui.py
+msgid "Confirm notebook mode"
+msgstr "确认笔电模式"
+
+#: ../py/test/pytests/tablet_mode_ui.py
+msgid "Failure"
+msgstr "失败"
+
+#: ../py/test/pytests/tablet_rotation.py
+msgid ""
+"Rotate the tablet to correctly align the picture, holding it at an upright "
+"90-degree angle."
+msgstr "竖立平板电脑使其垂直于桌面,并开始旋转到对齐图片。"
+
+#: ../py/test/pytests/touchpad.py
+msgid "Please take off your fingers and then press SPACE to start testing..."
+msgstr "请将待测物放置于水平面上,并按空白键开始校准。"
+
+#: ../py/test/pytests/touchpad_hover.py
+msgid "Calibrating touchpad..."
+msgstr "触控面板校正中..."
+
+#: ../py/test/pytests/touchpad_hover.py
+msgid "Please put the hover-tool into the holder."
+msgstr "请将悬停测试用具放入支架中"
+
+#: ../py/test/pytests/touchpad_hover.py
+msgid "Please pull out the hover-tool from the holder."
+msgstr "请将悬停测试用具从支架移除"
+
+#: ../py/test/pytests/touchpad_hover.py
+msgid "Checking for false positive..."
+msgstr "进行假阳性检查..."
+
+#: ../py/test/pytests/touchscreen_uniformity.py
+msgid "Calibrating Touchscreen"
+msgstr "触屏校正中"
+
+#: ../py/test/pytests/touchscreen_uniformity.py
+msgid "ERROR: Touchscreen Not Found"
+msgstr "没有找到触屏"
+
+#: ../py/test/pytests/touchscreen_uniformity.py
+msgid "Testing References"
+msgstr "参考值测试中"
+
+#: ../py/test/pytests/touchscreen_uniformity.py
+msgid "Testing Deltas"
+msgstr "差量测试中"
+
+#: ../py/test/pytests/tpm_diagnosis.py
+msgid "TPM Self-diagnosis"
+msgstr "TPM 自我诊断"
+
+#: ../py/test/pytests/update_firmware.py
+msgid "Update Firmware"
+msgstr "更新韧体"
+
+#: ../py/test/pytests/update_kernel.py
+msgid "Update Kernel"
+msgstr "更新 Kernel"
+
+#: ../py/test/pytests/usb.py
+msgid "Plug device into each USB port, {num_usb_ports} to go...<br>"
+msgstr "在每个 USB 端口插入装置, 还有 {num_usb_ports} 个待测试...<br>"
+
+#: ../py/test/pytests/verify_components.py
+msgid "Components Verification Test"
+msgstr "元件验证测试"
+
+#: ../py/test/pytests/verify_components.py
+msgid "Checking components..."
+msgstr "元件验证中..."
+
+#: ../py/test/pytests/vpd.py
+msgid "Fetching VPD from shop floor server..."
+msgstr "从 Shop Floor 服务器抓取 VPD 中..."
+
+#: ../py/test/pytests/vpd.py
+msgid "Writing VPD:<br>"
+msgstr "写入 VPD:<br>"
+
+#: ../py/test/pytests/vpd.py
+msgid "Select region:<br>"
+msgstr "选择区域代码:<br>"
+
+#: ../py/test/pytests/vpd.py
+msgid "<br>Select with ENTER"
+msgstr "<br>按 ENTER 选择"
+
+#: ../py/test/pytests/vpd.py
+msgid "Enter {vpd_label}: "
+msgstr "输入{vpd_label}: "
+
+#: ../py/test/pytests/vpd.py
+msgid "Select {vpd_label}: <br>"
+msgstr "选择{vpd_label}: <br>"
+
+#: ../py/test/pytests/vpd.py
+msgid "<br>(ESC to re-use current machine {vpd_label})"
+msgstr "<br>(ESC 使用目前已写入机器的{vpd_label})"
+
+#: ../py/test/pytests/vpd.py
+msgid "Found no valid {vpd_label} on machine."
+msgstr "机器上并无合法的{vpd_label}"
+
+#: ../py/test/pytests/vpd.py
+msgid "Invalid {vpd_label} value."
+msgstr "输入的{vpd_label}不合法"
+
+#: ../py/test/pytests/vpd.py
+msgid "Serial Number"
+msgstr "序号"
+
+#: ../py/test/pytests/vpd_from_http.py
+msgid "Please scan the panel serial number and press ENTER."
+msgstr "请扫描面板序号后按下 ENTER"
+
+#: ../py/test/pytests/vpd_from_http.py
+msgid "No VPD updated"
+msgstr "没有VPD需要更新"
+
 #: ../py/test/pytests/vswr/vswr.py
 msgid "Make sure the {name} antennta is connected to port {port}<br>"
 msgstr "连接 {name} 天线至 port {port}<br>"
@@ -186,3 +1693,72 @@
 #: ../py/test/pytests/vswr/vswr.py
 msgid "Then press key \"{key}\" to next stage."
 msgstr "完成后按 {key} 键"
+
+#: ../py/test/pytests/webrtc_camera.py
+msgid "Click \"Allow\" at the top of the screen."
+msgstr "点击上面的 \"Allow\" 按钮"
+
+#: ../py/test/pytests/webrtc_camera.py
+msgid ""
+"Click <a href=\"javascript:test.pass()\">pass</a> or <a href=\"javascript:"
+"test.fail()\">fail</a>."
+msgstr ""
+"请点击: <a href=\"javascript:test.pass()\">正常</a> 还是 <a href="
+"\"javascript:test.fail()\">不正常</a>"
+
+#: ../py/test/pytests/wifi_rf.py
+msgid "RMA Factory WiFi RF Test"
+msgstr ""
+
+#: ../py/test/pytests/wifi_rf.py
+msgid "WiFi RF Chamber Testing."
+msgstr "WiFi RF 测试"
+
+#: ../py/test/pytests/wifi_rf.py
+msgid "Remove device from chamber. Press SPACE when re-attached to network."
+msgstr "将装置从测试箱取出,重新连接网路后按下空白键"
+
+#: ../py/test/pytests/wifi_rf.py
+msgid "Place device in WiFi chamber. When ready to close chamber, press SPACE."
+msgstr "将设备放置在WiFi室。当您准备关闭室,按空白键。"
+
+#: ../py/test/pytests/wifi_throughput.py
+msgid ""
+"Please wait for other DUTs to finish WiFiThroughput test, and press spacebar "
+"to continue."
+msgstr "请等其它的 DUT 完成测试后按空白键继续。"
+
+#: ../py/test/pytests/wifi_throughput.py
+msgid "Running, please wait..."
+msgstr "测试中,请稍后。"
+
+#: ../py/test/pytests/wireless_antenna.py
+msgid "Switching to antenna {antenna}: "
+msgstr "切换到天线 {antenna}..."
+
+#: ../py/test/pytests/wireless_antenna.py
+#: ../py/test/pytests/wireless_radiotap.py
+msgid "Scanning on device {device} frequency {freq}..."
+msgstr "在装置 {device} 上扫描频率{freq}..."
+
+#: ../py/test/pytests/wireless_antenna.py
+#: ../py/test/pytests/wireless_radiotap.py
+msgid "Done scanning on device {device} frequency {freq}..."
+msgstr "在装置 {device} 上扫描频率{freq} 完成"
+
+#: ../py/test/pytests/wireless_antenna.py
+#: ../py/test/pytests/wireless_radiotap.py
+msgid "Press space to start scanning."
+msgstr "请按空白键开始扫描。"
+
+#: ../py/test/pytests/wireless_radiotap.py
+msgid "Switching to AP {ap}: "
+msgstr "切换到基地台 {ap}..."
+
+#: ../py/test/pytests/wireless_radiotap.py
+msgid "Checking frequencies..."
+msgstr "检查频率中..."
+
+#: ../py/test/pytests/write_device_data_to_vpd.py
+msgid "Writing device data to {vpd_section} VPD..."
+msgstr "机器资料正在写入到 {vpd_section} VPD..."
diff --git a/py/test/pytests/ac_power.py b/py/test/pytests/ac_power.py
index b352e66..e2d6a9c 100644
--- a/py/test/pytests/ac_power.py
+++ b/py/test/pytests/ac_power.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -14,28 +12,28 @@
 from cros.factory.device import device_utils
 from cros.factory.test import factory
 from cros.factory.test.fixture import bft_fixture
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 
 
-_TEST_TITLE_PLUG = test_ui.MakeLabel('Connect AC', u'连接充电器')
-_TEST_TITLE_UNPLUG = test_ui.MakeLabel('Remove AC', u'移除充电器')
+_TEST_TITLE_PLUG = i18n_test_ui.MakeI18nLabel('Connect AC')
+_TEST_TITLE_UNPLUG = i18n_test_ui.MakeI18nLabel('Remove AC')
 
-_PLUG_AC = lambda x: test_ui.MakeLabel(
-    'Plug in the charger' + (' (%s)' % x if x else ''),
-    u'请连接充电器' + (' (%s)' % x if x else ''))
-_UNPLUG_AC = test_ui.MakeLabel('Unplug the charger.', u'请移除充电器')
+_PLUG_AC = lambda type: (
+    i18n_test_ui.MakeI18nLabel('Plug in the charger ({type})', type=type)
+    if type else i18n_test_ui.MakeI18nLabel('Plug in the charger'))
+_UNPLUG_AC = i18n_test_ui.MakeI18nLabel('Unplug the charger.')
 
 _PROBE_TIMES_ID = 'probed_times'
-_PROBE_TIMES = lambda total: '%s <span id="%s">0</span> / %d' % (
-    test_ui.MakeLabel('Probed', u'侦测次数'), _PROBE_TIMES_ID, total)
+_PROBE_TIMES_MSG = lambda times, total: i18n_test_ui.MakeI18nLabel(
+    'Probed {times} / {total}', times=times, total=total)
 
 _AC_STATUS_ID = 'ac_status'
-_NO_AC = test_ui.MakeLabel('No AC adapter', u'沒有充电器')
-_AC_TYPE_PROBING = test_ui.MakeLabel('Identifying AC adapter...',
-                                     u'充电器型号识别中...')
-_AC_TYPE = test_ui.MakeLabel('AC adapter type: ', u'充电器型号: ')
+_NO_AC = i18n_test_ui.MakeI18nLabel('No AC adapter')
+_AC_TYPE_PROBING = i18n_test_ui.MakeI18nLabel('Identifying AC adapter...')
+_AC_TYPE = i18n_test_ui.MakeI18nLabel('AC adapter type: ')
 
 
 class ACPowerTest(unittest.TestCase):
@@ -80,10 +78,10 @@
                    if self.args.online else _UNPLUG_AC)
     probe_count_message = ''
     if self.args.retries is not None:
-      probe_count_message = _PROBE_TIMES(self.args.retries)
+      probe_count_message = _PROBE_TIMES_MSG(0, self.args.retries)
     self._template.SetState(
-        '%s<br>%s<div id="%s"></div>' %
-        (instruction, probe_count_message, _AC_STATUS_ID))
+        '%s<br><span id="%s">%s</span><div id="%s"></div>' %
+        (instruction, _PROBE_TIMES_ID, probe_count_message, _AC_STATUS_ID))
 
     self._power_state = {}
     self._done = threading.Event()
@@ -144,7 +142,8 @@
       if self.args.retries is not None:
         # retries is set.
         num_probes += 1
-        self._ui.SetHTML(str(num_probes), id=_PROBE_TIMES_ID)
+        self._ui.SetHTML(_PROBE_TIMES_MSG(num_probes, self.args.retries),
+                         id=_PROBE_TIMES_ID)
         if self.args.retries < num_probes:
           self.fail('Failed after probing %d times' % num_probes)
       # Prevent busy polling.
diff --git a/py/test/pytests/accelerometers_calibration.py b/py/test/pytests/accelerometers_calibration.py
index bf5f379..46555e8 100644
--- a/py/test/pytests/accelerometers_calibration.py
+++ b/py/test/pytests/accelerometers_calibration.py
@@ -64,29 +64,29 @@
 from cros.factory.device import accelerometer
 from cros.factory.device import device_utils
 from cros.factory.test import factory_task
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 
 
-_MSG_NOT_SUPPORTED = test_ui.MakeLabel('ERROR: The function is not supported.',
-                                       u'此功能尚未支持。', 'test-fail')
-_MSG_SPACE = test_ui.MakeLabel(
+_MSG_NOT_SUPPORTED = i18n_test_ui.MakeI18nLabelWithClass(
+    'ERROR: The function is not supported.', 'test-fail')
+_MSG_SPACE = i18n_test_ui.MakeI18nLabelWithClass(
     'Please put device on a horizontal plane then press space to '
-    'start calibration.',
-    u'请将待测物放置于水平面上,并按空白键开始校准。', 'test-info')
-_MSG_PREPARING_CALIBRATION = lambda t: test_ui.MakeLabel(
-    'Calibration will be started within %d seconds.'
-    'Please do not move device.' % t,
-    u'校准程序即将于 %d 秒后开始,请勿移动待测物。' % t, 'test-info')
-_MSG_CALIBRATION_IN_PROGRESS = test_ui.MakeLabel(
-    'Calibration is in progress, please do not move device.',
-    u'校准程序进行中,请勿移动待测物。', 'test-info')
-_MSG_PASS = test_ui.MakeLabel('PASS', u'成功', 'test-pass')
-_MSG_FAIL = test_ui.MakeLabel('FAIL', u'失败', 'test-fail')
+    'start calibration.', 'test-info')
+_MSG_PREPARING_CALIBRATION = lambda time: i18n_test_ui.MakeI18nLabelWithClass(
+    'Calibration will be started within {time} seconds.'
+    'Please do not move device.',
+    'test-info',
+    time=time)
+_MSG_CALIBRATION_IN_PROGRESS = i18n_test_ui.MakeI18nLabelWithClass(
+    'Calibration is in progress, please do not move device.', 'test-info')
+_MSG_PASS = i18n_test_ui.MakeI18nLabelWithClass('PASS', 'test-pass')
+_MSG_FAIL = i18n_test_ui.MakeI18nLabelWithClass('FAIL', 'test-fail')
 _MESSAGE_DELAY_SECS = 1
 
-_BR = '<br/>'
+_BR = '<br>'
 
 _CSS = """
   .test-info {font-size: 2em;}
diff --git a/py/test/pytests/accelerometers_lid_angle.py b/py/test/pytests/accelerometers_lid_angle.py
index 354cd33..fa184ad 100644
--- a/py/test/pytests/accelerometers_lid_angle.py
+++ b/py/test/pytests/accelerometers_lid_angle.py
@@ -31,20 +31,17 @@
 import factory_common  # pylint: disable=unused-import
 from cros.factory.device import accelerometer
 from cros.factory.device import device_utils
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 
 
-_MSG_PROMPT_BUILDER = lambda a: test_ui.MakeLabel(
-    'Please open the lid to %s degrees.' % a,
-    u'请将上盖掀开到 %s 度。' % a)
-_MSG_CONFIRM_BUILDER = lambda a: test_ui.MakeLabel(
-    'Confirm %s degrees' % a,
-    u'确认掀开到 %s 度' % a)
-_MSG_CHECKING = test_ui.MakeLabel(
-    'Checking angle...',
-    u'正在确认角度……')
+_MSG_PROMPT_BUILDER = lambda angle: i18n_test_ui.MakeI18nLabel(
+    'Please open the lid to {angle} degrees.', angle=angle)
+_MSG_CONFIRM_BUILDER = lambda angle: i18n_test_ui.MakeI18nLabel(
+    'Confirm {angle} degrees', angle=angle)
+_MSG_CHECKING = i18n_test_ui.MakeI18nLabel('Checking angle...')
 
 _ID_PROMPT = 'prompt'
 _ID_CONFIRM_BUTTON = 'confirm-button'
diff --git a/py/test/pytests/audio.py b/py/test/pytests/audio.py
index 94604d7..be529cc 100644
--- a/py/test/pytests/audio.py
+++ b/py/test/pytests/audio.py
@@ -16,6 +16,9 @@
 import factory_common  # pylint: disable=unused-import
 from cros.factory.device import device_utils
 from cros.factory.test import factory_task
+from cros.factory.test.i18n import _
+from cros.factory.test.i18n import arg_utils as i18n_arg_utils
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
@@ -23,17 +26,16 @@
 from cros.factory.utils import process_utils
 from cros.factory.utils import sync_utils
 
-_TEST_TITLE = test_ui.MakeLabel('Audio Test', u'音讯测试')
+_TEST_TITLE = i18n_test_ui.MakeI18nLabel('Audio Test')
 
 _DIV_CENTER_INSTRUCTION = """
 <div id='instruction-center' class='template-instruction'></div>"""
 _CSS = '#pass_key {font-size:36px; font-weight:bold;}'
 
-_INSTRUCTION_AUDIO_RANDOM_TEST = lambda d, k: test_ui.MakeLabel(
-    '</br>'.join(['Press the number you hear from %s to pass the test.' % d,
-                  'Press "%s" to replay.' % k]),
-    '</br>'.join([u'请按你从 %s 输出所听到的数字' % d,
-                  u'按 %s 重播语音' % k]))
+_INSTRUCTION_AUDIO_RANDOM_TEST = lambda device, key: i18n_test_ui.MakeI18nLabel(
+    'Press the number you hear from {device} to pass the test.<br>'
+    'Press "{key}" to replay.',
+    device=device, key=key)
 
 _SOUND_DIRECTORY = os.path.join(
     os.path.dirname(os.path.realpath(__file__)), '..', '..', 'goofy',
@@ -51,7 +53,7 @@
     _dut: dut instance
     ui: cros.factory.test.test_ui object.
     port_label: Label name of audio port to output. It should be generated
-        using test_ui.MakeLabel to have English/Chinese version.
+        using i18n_test_ui.MakeI18nLabel to have internationalized version.
     title_id: HTML id for placing testing title.
     instruction_id: HTML id for placing instruction.
     card: audio card to output.
@@ -73,9 +75,9 @@
     self._sample_rate = sample_rate
 
     if channel == 'left':
-      self._port_label += test_ui.MakeLabel(' (Left Channel)', u'(左声道)')
+      self._port_label += i18n_test_ui.MakeI18nLabel(' (Left Channel)')
     elif channel == 'right':
-      self._port_label += test_ui.MakeLabel(' (Right Channel)', u'(右声道)')
+      self._port_label += i18n_test_ui.MakeI18nLabel(' (Right Channel)')
 
   def _InitUI(self):
     self._ui.SetHTML(self._port_label, id=self._title_id)
@@ -153,13 +155,12 @@
     self._instruction_id = instruction_id
     self._wait_for_connect = wait_for_connect
     if wait_for_connect:
-      self._title = test_ui.MakeLabel('Connect Headphone', u'连接耳机')
-      self._instruction = test_ui.MakeLabel('Please plug headphone in.',
-                                            u'请接上耳机')
+      self._title = i18n_test_ui.MakeI18nLabel('Connect Headphone')
+      self._instruction = i18n_test_ui.MakeI18nLabel(
+          'Please plug headphone in.')
     else:
-      self._title = test_ui.MakeLabel('Discnnect Headphone', u'移除耳机')
-      self._instruction = test_ui.MakeLabel('Please unplug headphone.',
-                                            u'请拔下耳机')
+      self._title = i18n_test_ui.MakeI18nLabel('Disconnect Headphone')
+      self._instruction = i18n_test_ui.MakeI18nLabel('Please unplug headphone.')
 
   def _InitUI(self):
     self._ui.SetHTML(self._title, id=self._title_id)
@@ -195,8 +196,10 @@
       Arg('output_dev', tuple,
           'Onput ALSA device. (card_name, sub_device).'
           'For example: ("audio_card", "0").', ('0', '0')),
-      Arg('port_label', tuple, 'Label of audio (en, zh).',
-          default=('Internal Speaker', u'内建喇叭')),
+      i18n_arg_utils.I18nArg(
+          'port_label', 'Label of audio.',
+          default=_('Internal Speaker'),
+          accept_tuple=True),
       Arg('test_left_right', bool, 'Test left and right channel.',
           default=True),
       Arg('require_headphone', bool, 'Require headphone option', False),
@@ -208,6 +211,7 @@
   ]
 
   def setUp(self):
+    i18n_arg_utils.ParseArg(self, 'port_label')
     self._dut = device_utils.CreateDUTInterface()
     if self.args.audio_conf:
       self._dut.audio.ApplyConfig(self.args.audio_conf)
@@ -258,7 +262,8 @@
       tasks.append(DetectHeadphoneTask(self._dut, self._out_card, self._ui,
                                        self.args.require_headphone, _TITLE_ID,
                                        _INSTRUCTION_ID))
-    args = (self._dut, self._ui, test_ui.MakeLabel(*self.args.port_label),
+    args = (self._dut, self._ui,
+            i18n_test_ui.MakeI18nLabel(self.args.port_label),
             _TITLE_ID, _INSTRUCTION_ID, self._out_card, self._out_device)
     _ComposeLeftRightTasks(tasks, args)
 
diff --git a/py/test/pytests/audio_basic.py b/py/test/pytests/audio_basic.py
index e4ed1b7..2d4007e 100644
--- a/py/test/pytests/audio_basic.py
+++ b/py/test/pytests/audio_basic.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -19,6 +18,9 @@
 
 import factory_common  # pylint: disable=unused-import
 from cros.factory.device import device_utils
+from cros.factory.test.i18n import _
+from cros.factory.test.i18n import arg_utils as i18n_arg_utils
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
@@ -32,17 +34,15 @@
     'static', 'sounds')
 
 
-_MSG_AUDIO_INFO = test_ui.MakeLabel(
-    'Press \'P\' to first play a sample for each channel to ensure audio '
+_MSG_AUDIO_INFO = i18n_test_ui.MakeI18nLabelWithClass(
+    "Press 'P' to first play a sample for each channel to ensure audio "
     'output works.<br>'
-    'Press \'R\' to record %d seconds, Playback will follow<br>'
-    'Press space to mark pass' % _RECORD_SEC,
-    zh='按 \'P\' 键播放范例<br>'
-    '按 \'R\' 键开始录音%d秒,之后会重播录到的声音<br>'
-    '压下空白表示成功' % _RECORD_SEC,
-    css_class='audio-test-info')
-_MSG_RECORD_INFO = test_ui.MakeLabel('Start recording', u'开始录音',
-                                     css_class='audio-test-info')
+    "Press 'R' to record {record_sec} seconds, Playback will follow<br>"
+    'Press space to mark pass',
+    'audio-test-info',
+    record_sec=_RECORD_SEC)
+_MSG_RECORD_INFO = i18n_test_ui.MakeI18nLabelWithClass('Start recording',
+                                                       'audio-test-info')
 _HTML_AUDIO = """
 <table style="width: 70%%; margin: auto;">
   <tr>
@@ -71,21 +71,23 @@
 
 
 def GetPlaybackRecordLabel(channel):
-  return test_ui.MakeLabel('Playback sound (Mic channel %d)' % channel,
-                           u'重播录到的声音(麦克风通道%d)' % channel,
-                           css_class='audio-test-info')
+  return i18n_test_ui.MakeI18nLabelWithClass(
+      'Playback sound (Mic channel {channel})',
+      'audio-test-info',
+      channel=channel)
 
 
 def GetPlaybackLabel(channel):
-  return test_ui.MakeLabel('Playback sound to channel %d' % channel,
-                           u'播放范例到通道%d)' % channel,
-                           css_class='audio-test-info')
+  return i18n_test_ui.MakeI18nLabelWithClass(
+      'Playback sound to channel {channel}', 'audio-test-info', channel=channel)
 
 
 class AudioBasicTest(unittest.TestCase):
   ARGS = [
-      Arg('audio_title', tuple, 'Label Title of audio test (en, zh)',
-          ('Headset', u'外接耳机')),
+      i18n_arg_utils.I18nArg(
+          'audio_title', 'Label Title of audio test',
+          default=_('Headset'),
+          accept_tuple=True),
       Arg('audio_conf', str, 'Audio config file path', optional=True),
       Arg('initial_actions', list, 'List of tuple (card, actions)', []),
       Arg('input_dev', tuple,
@@ -99,6 +101,7 @@
   ]
 
   def setUp(self):
+    i18n_arg_utils.ParseArg(self, 'audio_title')
     self._dut = device_utils.CreateDUTInterface()
     if self.args.audio_conf:
       self._dut.audio.ApplyConfig(self.args.audio_conf)
@@ -123,9 +126,8 @@
     self.ui.BindKey('P', self.HandleSampleEvent)
     self.ui.BindKey(test_ui.SPACE_KEY, self.MarkPass)
 
-    msg_audio_title = test_ui.MakeLabel(
-        self.args.audio_title[0], self.args.audio_title[1],
-        css_class='audio-test-info')
+    msg_audio_title = i18n_test_ui.MakeI18nLabelWithClass(
+        self.args.audio_title, 'audio-test-info')
     self.ui.SetHTML(msg_audio_title, id='audio_title')
     self.ui.SetHTML(_MSG_AUDIO_INFO, id='audio_info')
     self.current_process = None
diff --git a/py/test/pytests/audio_loop/audio_loop.py b/py/test/pytests/audio_loop/audio_loop.py
index 9476401..539d8bc 100644
--- a/py/test/pytests/audio_loop/audio_loop.py
+++ b/py/test/pytests/audio_loop/audio_loop.py
@@ -101,6 +101,7 @@
 from cros.factory.device import device_utils
 from cros.factory.test import event as test_event
 from cros.factory.test import factory
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.test.utils import audio_utils
@@ -144,21 +145,19 @@
 # Default duration in seconds to trim in the beginning of recorded file.
 _DEFAULT_TRIM_SECONDS = 0.5
 
-_UI_HTML = """
+_UI_HTML = ("""
 <h1 id="message" style="position:absolute; top:45%">
 <center style="font-size: 20pt">
     <div id="test_title">
     </div>
     <div id="require_dongle">
-        <span class="goofy-label-en">Plug in audio jack dongle</span>
-        <span class="goofy-label-zh">請放入音源孔測試置具</span>
+""" + i18n_test_ui.MakeI18nLabel('Plug in audio jack dongle') + """
     </div>
-    <br/>
-    <span class="goofy-label-en">Hit s to start loopback test</span>
-    <span class="goofy-label-zh">请按下s键开始音源回放测试</span>
+    <br>
+""" + i18n_test_ui.MakeI18nLabel('Hit s to start loopback test') + """
 </center>
 </h1>
-"""
+""")
 
 MicSource = type_utils.Enum(['external', 'panel', 'mlb'])
 
diff --git a/py/test/pytests/audio_quality.py b/py/test/pytests/audio_quality.py
index 3c0085b..2753617 100644
--- a/py/test/pytests/audio_quality.py
+++ b/py/test/pytests/audio_quality.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -31,6 +29,7 @@
 from cros.factory.test.env import paths
 from cros.factory.test import event_log
 from cros.factory.test import factory
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import shopfloor
 from cros.factory.test import test_ui
 from cros.factory.test.utils import audio_utils
@@ -54,32 +53,29 @@
 _FIXTURE_PARAMETERS = ['audio/audio_md5', 'audio/audio.zip']
 
 # Label strings.
-_LABEL_SPACE_TO_START = test_ui.MakeLabel(
-    'Press \'Space\' to start test', u'按空白键开始测试')
-_LABEL_CONNECTED = test_ui.MakeLabel('Connected', u'已连线')
-_LABEL_WAITING = test_ui.MakeLabel('Waiting for command', u'等待指令中')
-_LABEL_AUDIOLOOP = test_ui.MakeLabel('Audio looping', u'音源回放中')
-_LABEL_SPEAKER_MUTE_OFF = test_ui.MakeLabel('Speaker on', u'喇叭开启')
-_LABEL_DMIC_ON = test_ui.MakeLabel('LCD Dmic on', u'LCD mic开启')
-_LABEL_MLBDMIC_ON = test_ui.MakeLabel('MLB Dmic on', u'MLB mic开启')
-_LABEL_PLAYTONE_LEFT = test_ui.MakeLabel(
-    'Playing tone to left channel', u'播音至左声道')
-_LABEL_PLAYTONE_RIGHT = test_ui.MakeLabel(
-    'Playing tone to right channel', u'播音至右声道')
-_LABEL_WAITING_IP = test_ui.MakeLabel(
-    'Waiting for IP address', u'等待 IP 设定')
-_LABEL_CONNECT_SHOPFLOOR = test_ui.MakeLabel(
-    'Connecting to ShopFloor...', u'连接到 ShopFloor 中...')
-_LABEL_DOWNLOADING_PARAMETERS = test_ui.MakeLabel(
-    'Downloading parameters', u'下载测试规格中')
-_LABEL_REMOVE_ETHERNET = test_ui.MakeLabel(
-    'Remove Ethernet connectivity', u'移除网路介面卡')
-_LABEL_WAITING_ETHERNET = test_ui.MakeLabel(
-    'Waiting for Ethernet connectivity to audio fixture',
-    u'等待网路介面卡连接到 audio 置具')
-_LABEL_READY = test_ui.MakeLabel(
-    'Ready for connection', u'準备完成,等待链接')
-_LABEL_UPLOAD_AUXLOG = test_ui.MakeLabel('Upload log', u'上传记录档')
+_LABEL_SPACE_TO_START = i18n_test_ui.MakeI18nLabel(
+    "Press 'Space' to start test")
+_LABEL_CONNECTED = i18n_test_ui.MakeI18nLabel('Connected')
+_LABEL_WAITING = i18n_test_ui.MakeI18nLabel('Waiting for command')
+_LABEL_AUDIOLOOP = i18n_test_ui.MakeI18nLabel('Audio looping')
+_LABEL_SPEAKER_MUTE_OFF = i18n_test_ui.MakeI18nLabel('Speaker on')
+_LABEL_DMIC_ON = i18n_test_ui.MakeI18nLabel('LCD Dmic on')
+_LABEL_MLBDMIC_ON = i18n_test_ui.MakeI18nLabel('MLB Dmic on')
+_LABEL_PLAYTONE_LEFT = i18n_test_ui.MakeI18nLabel(
+    'Playing tone to left channel')
+_LABEL_PLAYTONE_RIGHT = i18n_test_ui.MakeI18nLabel(
+    'Playing tone to right channel')
+_LABEL_WAITING_IP = i18n_test_ui.MakeI18nLabel('Waiting for IP address')
+_LABEL_CONNECT_SHOPFLOOR = i18n_test_ui.MakeI18nLabel(
+    'Connecting to ShopFloor...')
+_LABEL_DOWNLOADING_PARAMETERS = i18n_test_ui.MakeI18nLabel(
+    'Downloading parameters')
+_LABEL_REMOVE_ETHERNET = i18n_test_ui.MakeI18nLabel(
+    'Remove Ethernet connectivity')
+_LABEL_WAITING_ETHERNET = i18n_test_ui.MakeI18nLabel(
+    'Waiting for Ethernet connectivity to audio fixture')
+_LABEL_READY = i18n_test_ui.MakeI18nLabel('Ready for connection')
+_LABEL_UPLOAD_AUXLOG = i18n_test_ui.MakeI18nLabel('Upload log')
 _LABEL_FAIL_LOGS = 'Test fail, find more detail in log.'
 
 # Regular expression to match external commands.
diff --git a/py/test/pytests/bad_blocks.py b/py/test/pytests/bad_blocks.py
index 68bdb45..28afba5 100644
--- a/py/test/pytests/bad_blocks.py
+++ b/py/test/pytests/bad_blocks.py
@@ -1,5 +1,4 @@
 #!/usr/bin/python
-# -*- coding: utf-8 -*-
 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -28,6 +27,7 @@
 from cros.factory.device import device_utils
 from cros.factory.test import event_log
 from cros.factory.test import factory
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
@@ -239,8 +239,9 @@
         params.sector_size / 1024. ** 2)
 
     self.template.SetInstruction(
-        test_ui.MakeLabel('Testing %s region of storage' % test_size_mb,
-                          '正在测试 %s 的 存储 空间' % test_size_mb))
+        i18n_test_ui.MakeI18nLabel(
+            'Testing {test_size_mb} region of storage',
+            test_size_mb=test_size_mb))
 
     # Kill any badblocks processes currently running
     self.dut.Call(['killall', 'badblocks'])
@@ -277,8 +278,10 @@
     def UpdatePhase():
       event_log.Log('start_phase', current_phase=current_phase)
       self.ui.SetHTML(
-          test_ui.MakeLabel('Phase', '阶段') + ' %d/%d: ' % (
-              min(current_phase + 1, total_phases), total_phases),
+          i18n_test_ui.MakeI18nLabel(
+              'Phase {current_phase}/{total_phases}: ',
+              current_phase=min(current_phase + 1, total_phases),
+              total_phases=total_phases),
           id='bb-phase')
     UpdatePhase()
 
diff --git a/py/test/pytests/barcode_scan_to_file.py b/py/test/pytests/barcode_scan_to_file.py
index 4001952..7d41a3c 100644
--- a/py/test/pytests/barcode_scan_to_file.py
+++ b/py/test/pytests/barcode_scan_to_file.py
@@ -1,5 +1,3 @@
-# -*- mode: python; coding: utf-8 -*-
-#
 # Copyright 2014 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -17,6 +15,10 @@
 from cros.factory.device import device_utils
 from cros.factory.test import factory
 from cros.factory.test.fixture.whale import whale_bft_fixture
+from cros.factory.test import i18n
+from cros.factory.test.i18n import _
+from cros.factory.test.i18n import arg_utils as i18n_arg_utils
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
@@ -26,12 +28,9 @@
 
 class BarcodeScanToFileTest(unittest.TestCase):
   """Scans barcode and saves it to a specific file."""
-  ARGS = [
-      Arg('label_en', (str, unicode), 'Name of the barcode to scan'),
-      Arg('label_zh', (str, unicode),
-          'Chinese name of barcode being scanned '
-          '(defaults to the same as the English label)',
-          optional=True),
+  ARGS = (i18n_arg_utils.BackwardCompatibleI18nArgs(
+      'label', 'Name of the barcode to scan'
+  ) + [
       Arg('regexp', str, 'Regexp that the scanned value must match',
           optional=True),
       Arg('ignore_case', bool, 'True to ignore case from input.',
@@ -41,11 +40,11 @@
           'Parameters to initialize WhaleBFTFixture. It is a dict which '
           'contains at least "host" and "port" that points to BeagleBone '
           'servod.',
-          optional=True)]
+          optional=True)])
 
-  def ShowError(self, message, message_zh):
-    logging.info('Scan error: %r', message)
-    error_message = test_ui.MakeLabel(message, message_zh)
+  def ShowError(self, message):
+    logging.info('Scan error: %r', message['en-US'])
+    error_message = i18n_test_ui.MakeI18nLabel(message)
     self.ui.SetHTML(
         '<span class="test-error">%s</span>' % error_message,
         id='scan-status')
@@ -62,16 +61,14 @@
       scan_value = scan_value.upper()
     esc_scan_value = test_ui.Escape(scan_value)
     if not scan_value:
-      self.ShowError('The scanned value is empty.',
-                     u'扫描编号是空的。')
+      self.ShowError(_('The scanned value is empty.'))
       return
     if self.args.regexp:
       match = re.match(self.args.regexp, scan_value)
       if not match or match.group(0) != scan_value:
-        self.ShowError(
-            'The scanned value "%s" does not match '
-            'the expected format.' % esc_scan_value,
-            u'所扫描的编号「%s」格式不对。' % esc_scan_value)
+        self.ShowError(i18n.StringFormat(
+            _('The scanned value "{scan_value}" does not match '
+              'the expected format.'), scan_value=esc_scan_value))
         return
 
     # save scan value
@@ -86,6 +83,7 @@
     self.ui.Pass()
 
   def setUp(self):
+    i18n_arg_utils.ParseArg(self, 'label')
     self.ui = test_ui.UI()
     self.dut = device_utils.CreateDUTInterface()
     if self.args.bft_params is not None:
@@ -100,20 +98,12 @@
   def runTest(self):
     template = ui_templates.OneSection(self.ui)
 
-    label_zh = self.args.label_zh or self.args.label_en
-    # A workaround that some existing test lists do not use unicode
-    # for Chinese string.
-    if type(label_zh) is str:
-      label_zh = unicode(label_zh, encoding='utf-8')
-
-    template.SetTitle(test_ui.MakeLabel(
-        'Scan %s' % self.args.label_en.title(),
-        u'扫描%s' % label_zh))
+    template.SetTitle(
+        i18n_test_ui.MakeI18nLabel('Scan {label}', label=self.args.label))
 
     template.SetState(
-        test_ui.MakeLabel(
-            'Please scan the %s and press ENTER.' % self.args.label_en,
-            u'请扫描%s后按下 ENTER。' % label_zh) +
+        i18n_test_ui.MakeI18nLabel(
+            'Please scan the {label} and press ENTER.', label=self.args.label) +
         '<br><input id="scan-value" type="text" size="20" tabindex="1">'
         '<p id="scan-status">')
     self.ui.SetFocus('scan-value')
diff --git a/py/test/pytests/battery_current.py b/py/test/pytests/battery_current.py
index db07390..20baf79 100644
--- a/py/test/pytests/battery_current.py
+++ b/py/test/pytests/battery_current.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -19,32 +17,31 @@
 
 import factory_common  # pylint: disable=unused-import
 from cros.factory.device import device_utils
+from cros.factory.test import i18n
+from cros.factory.test.i18n import _
+from cros.factory.test.i18n import arg_utils as i18n_arg_utils
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 from cros.factory.utils import sync_utils
 
-_TEST_TITLE = test_ui.MakeLabel('Battery Current Test', u'充電放電电流測試')
+_TEST_TITLE = i18n_test_ui.MakeI18nLabel('Battery Current Test')
 
 
 def _PROMPT_TEXT(charge, current, target):
-  return test_ui.MakeLabel(
-      'Waiting for %s current to meet %d mA. (Currently %s at %d mA)' %
-      ('charging' if charge else 'discharging',
-       target,
-       'charging' if current >= 0 else 'discharging',
-       abs(current)),
-      u'等待%s电流大于 %d mA. (目前%s中:%d mA)' %
-      (u'充电' if charge else u'放电',
-       target,
-       u'充电' if current >= 0 else u'放电',
-       abs(current)))
+  return i18n_test_ui.MakeI18nLabel(
+      'Waiting for {target_status} current to meet {target_current} mA.'
+      ' (Currently {status} at {current} mA)',
+      target_status=_('charging') if charge else _('discharging'),
+      target_current=target,
+      status=_('charging') if current >= 0 else _('discharging'),
+      current=abs(current))
 
 _CHARGE_TEXT = lambda c, t: _PROMPT_TEXT(True, c, t)
 _DISCHARGE_TEXT = lambda c, t: _PROMPT_TEXT(False, c, t)
-_USBPDPORT_PROMPT = (lambda en, zh, v:
-                     test_ui.MakeLabel('Insert power to %s(%dmV)' % (en, v),
-                                       u'请将电源线插入%s(%dmV)' % (zh, v)))
+_USBPDPORT_PROMPT = (lambda prompt, v: i18n_test_ui.MakeI18nLabel(
+    'Insert power to {prompt}({voltage}mV)', prompt=prompt, voltage=v))
 
 
 class BatteryCurrentTest(unittest.TestCase):
@@ -60,6 +57,7 @@
       Arg('max_battery_level', int,
           'maximum allowed starting battery level', optional=True),
       Arg('usbpd_info', tuple, textwrap.dedent("""
+          (usbpd_port, min_millivolt, max_millivolt) or
           (usbpd_port, usbpd_port_prompt, min_millivolt, max_millivolt)
           Used to select a particular port from a multi-port DUT.
 
@@ -73,13 +71,21 @@
                                provide
           * ``max_millivolt``: (int) The maximum millivolt the power must
                                provide
+
+          ``usbpd_prompt`` should be used instead of
+          ``usbpd_port_prompt_{en,zh}``, which doesn't support i18n.
           """),
-          optional=True)
+          optional=True),
+      i18n_arg_utils.I18nArg('usbpd_prompt',
+                             'prompt operator which port to insert',
+                             default='')
   ]
 
   def setUp(self):
     """Sets the test ui, template and the thread that runs ui. Initializes
     _power."""
+    i18n_arg_utils.ParseArg(self, 'usbpd_prompt')
+
     self._dut = device_utils.CreateDUTInterface()
     self._power = self._dut.power
     self._ui = test_ui.UI()
@@ -88,15 +94,28 @@
     if self.args.usbpd_info:
       self._CheckUSBPDInfoArg(self.args.usbpd_info)
       self._usbpd_port = self.args.usbpd_info[0]
-      self._usbpd_prompt_en = self.args.usbpd_info[1]
-      self._usbpd_prompt_zh = self.args.usbpd_info[2]
-      self._usbpd_min_millivolt = self.args.usbpd_info[3]
-      self._usbpd_max_millivolt = self.args.usbpd_info[4]
+      # TODO(pihsun): This is to maintain backward compatibility. Should be
+      #               removed after test lists are migrated to new format.
+      if len(self.args.usbpd_info) == 5:
+        self.args.usbpd_prompt = i18n.Translated({
+            'en-US': self.args.usbpd_info[1],
+            'zh-CN': self.args.usbpd_info[2]
+        }, translate=False)
+        self._usbpd_min_millivolt = self.args.usbpd_info[3]
+        self._usbpd_max_millivolt = self.args.usbpd_info[4]
+      else:
+        self._usbpd_min_millivolt = self.args.usbpd_info[1]
+        self._usbpd_max_millivolt = self.args.usbpd_info[2]
+    self._usbpd_prompt = self.args.usbpd_prompt
 
   def _CheckUSBPDInfoArg(self, info):
-    check_types = (int, basestring, basestring, int, int)
-    if len(info) != 5:
+    if len(info) == 5:
+      check_types = (int, basestring, basestring, int, int)
+    elif len(info) == 3:
+      check_types = (int, int, int)
+    else:
       raise ValueError('ERROR: invalid usbpd_info item: ' + str(info))
+
     for i in xrange(len(info)):
       if not isinstance(info[i], check_types[i]):
         logging.error('(%s)usbpd_info[%d] type is not %s', type(info[i]), i,
@@ -111,16 +130,14 @@
 
   def _CheckUSBPD(self):
     status = self._dut.usb_c.GetPDPowerStatus()
-    self._template.SetState(_USBPDPORT_PROMPT(self._usbpd_prompt_en,
-                                              self._usbpd_prompt_zh, 0))
+    self._template.SetState(_USBPDPORT_PROMPT(self._usbpd_prompt, 0))
     if 'millivolt' not in status[self._usbpd_port]:
       logging.info('No millivolt detected in port %d', self._usbpd_port)
       return False
     millivolt = status[self._usbpd_port]['millivolt']
     logging.info('millivolt %d, acceptable range (%d, %d)', millivolt,
                  self._usbpd_min_millivolt, self._usbpd_max_millivolt)
-    self._template.SetState(_USBPDPORT_PROMPT(self._usbpd_prompt_en,
-                                              self._usbpd_prompt_zh, millivolt))
+    self._template.SetState(_USBPDPORT_PROMPT(self._usbpd_prompt, millivolt))
     return (self._usbpd_min_millivolt <= millivolt and
             millivolt <= self._usbpd_max_millivolt)
 
diff --git a/py/test/pytests/blocking_charge.py b/py/test/pytests/blocking_charge.py
index 9b9ede7..8144c7b 100644
--- a/py/test/pytests/blocking_charge.py
+++ b/py/test/pytests/blocking_charge.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -17,11 +15,12 @@
 import factory_common  # pylint: disable=unused-import
 from cros.factory.device import device_utils
 from cros.factory.test import event_log
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 
-_TEST_TITLE = test_ui.MakeLabel('Charging', u'充电')
+_TEST_TITLE = i18n_test_ui.MakeI18nLabel('Charging')
 
 
 def FormatTime(seconds):
@@ -29,12 +28,12 @@
 
 
 def MakeChargeTextLabel(start, current, target, elapsed, remaining):
-  _LABEL_EN = ('Charging to %d%% (Start: %d%%. Current: %d%%.)<br>' +
-               'Time elapsed: %s' + '&nbsp;' * 8 + 'Time remaining: %s')
-  _LABEL_ZH = (u'充电至 %d%% (起始电量: %d%%. 当前电量: %d%%.)<br>' +
-               u'经过时间: %s' + u'&nbsp;' * 8 + u'剩余时间: %s')
-  values = (target, start, current, FormatTime(elapsed), FormatTime(remaining))
-  return test_ui.MakeLabel(_LABEL_EN % values, _LABEL_ZH % values)
+  return i18n_test_ui.MakeI18nLabel(
+      'Charging to {target}% (Start: {start}%. Current: {current}%.)<br>'
+      'Time elapsed: {elapsed}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'
+      'Time remaining: {remaining}',
+      target=target, start=start, current=current,
+      elapsed=FormatTime(elapsed), remaining=FormatTime(remaining))
 
 
 def MakeSpriteHTMLTag(src, height, width):
diff --git a/py/test/pytests/bluetooth.py b/py/test/pytests/bluetooth.py
index 938a7ea..5cf6a00 100644
--- a/py/test/pytests/bluetooth.py
+++ b/py/test/pytests/bluetooth.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -30,6 +28,7 @@
 from cros.factory.test import event_log
 from cros.factory.test import factory
 from cros.factory.test import factory_task
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import shopfloor
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
@@ -39,86 +38,60 @@
 from cros.factory.utils import sync_utils
 
 
-_TEST_TITLE = test_ui.MakeLabel('Bluetooth functional Test', u'蓝牙功能测试')
-_MSG_DETECT_ADAPTER = test_ui.MakeLabel(
-    'Detect bluetooth adapter', u'检测蓝牙适配器')
-_MSG_TURN_ON_DEVICE = test_ui.MakeLabel(
+_TEST_TITLE = i18n_test_ui.MakeI18nLabel('Bluetooth functional Test')
+_MSG_DETECT_ADAPTER = i18n_test_ui.MakeI18nLabel('Detect bluetooth adapter')
+_MSG_TURN_ON_DEVICE = i18n_test_ui.MakeI18nLabelWithClass(
     'Enable the connection ability of bluetooth device and press Enter',
-    u'启用蓝牙装置的连接功能然后按输入键',
     'start-font-size')
-_MSG_INTO_FIXTURE = test_ui.MakeLabel(
+_MSG_INTO_FIXTURE = i18n_test_ui.MakeI18nLabelWithClass(
     'Place the base into the fixture, '
-    'and press the space key on the test host.',
-    u'请把测试键盘放入测试机具中,然後按下电脑的 space 键',
+    'and press the space key on the test host.', 'start-font-size')
+_MSG_RESET_MAGNET = i18n_test_ui.MakeI18nLabelWithClass(
+    'Please re-attach the magnet, and press the space key on the test host.',
     'start-font-size')
-_MSG_RESET_MAGNET = test_ui.MakeLabel(
-    'Please re-attach the magnet.',
-    u'请重新連結磁鐵,然後按下电脑的 space 键',
-    'start-font-size')
-_MSG_START_CHARGE = test_ui.MakeLabel(
+_MSG_START_CHARGE = i18n_test_ui.MakeI18nLabelWithClass(
     'Turn on charging by pressing the green button, '
     'take the keyboard out and put it back, '
-    'and press the space key on the test host.',
-    u'请按下绿色键开始充电, 然後取出再放回键盘, 最後按下电脑的 space 键',
-    'start-font-size')
-_MSG_READ_BATTERY_1 = test_ui.MakeLabel(
-    'Read battery level for the 1st time.',
-    u'第1次读取电池电量',
-    'start-font-size')
-_MSG_READ_BATTERY_2 = test_ui.MakeLabel(
-    'Read battery level for the 2nd time.',
-    u'第2次读取电池电量',
-    'start-font-size')
-_MSG_BATTERY_CHARGE_TEST = test_ui.MakeLabel(
+    'and press the space key on the test host.', 'start-font-size')
+_MSG_READ_BATTERY_1 = i18n_test_ui.MakeI18nLabelWithClass(
+    'Read battery level for the 1st time.', 'start-font-size')
+_MSG_READ_BATTERY_2 = i18n_test_ui.MakeI18nLabelWithClass(
+    'Read battery level for the 2nd time.', 'start-font-size')
+_MSG_BATTERY_CHARGE_TEST = i18n_test_ui.MakeI18nLabelWithClass(
     'Check if the battery has charged to a higher percentage',
-    u'检查充电之後电量是否增加',
     'start-font-size')
-_MSG_CHECK_BATTERY_LEVEL = test_ui.MakeLabel(
-    'Check battery level.',
-    u'检查电池电量',
-    'start-font-size')
-_MSG_STOP_CHARGE = test_ui.MakeLabel(
+_MSG_CHECK_BATTERY_LEVEL = i18n_test_ui.MakeI18nLabelWithClass(
+    'Check battery level.', 'start-font-size')
+_MSG_STOP_CHARGE = i18n_test_ui.MakeI18nLabelWithClass(
     'Press the green button again to stop charging, '
-    'and press the space key on the test host.',
-    u'请按下绿色键以停止充电,然後按下电脑的 space 键',
-    'start-font-size')
-_MSG_OUT_OF_FIXTURE = test_ui.MakeLabel(
+    'and press the space key on the test host.', 'start-font-size')
+_MSG_OUT_OF_FIXTURE = i18n_test_ui.MakeI18nLabelWithClass(
     'Take the base out of the fixture, '
-    'and press the space key on the test host.',
-    u'請把測試鍵盤取出,然後按下电脑的 space 键',
-    'start-font-size')
-_MSG_READ_FIRMWARE_REVISION_STRING = test_ui.MakeLabel(
-    'Read firmware revision string.',
-    u'读取键盘韧体版本',
-    'start-font-size')
-_MSG_SCAN_DEVICE = test_ui.MakeLabel(
-    'Scanning...', u'扫描中...', 'start-font-size')
-_RAW_MSG_DETECT_RSSI = ['Detect RSSI (count %d/%d)', u'侦测RSSI (第 %d/%d 次)',
-                        'start-font-size']
-_MSG_TURN_ON_INPUT_DEVICE = test_ui.MakeLabel(
+    'and press the space key on the test host.', 'start-font-size')
+_MSG_READ_FIRMWARE_REVISION_STRING = i18n_test_ui.MakeI18nLabelWithClass(
+    'Read firmware revision string.', 'start-font-size')
+_MSG_SCAN_DEVICE = i18n_test_ui.MakeI18nLabelWithClass(
+    'Scanning...', 'start-font-size')
+_MSG_DETECT_RSSI = lambda count, total: (
+    i18n_test_ui.MakeI18nLabelWithClass(
+        'Detect RSSI (count {count}/{total})',
+        'start-font-size', count=count, total=total))
+_MSG_TURN_ON_INPUT_DEVICE = i18n_test_ui.MakeI18nLabelWithClass(
     'Enable the connection ability of input bluetooth device and press Enter',
-    u'启用蓝牙输入装置的连接功能然后按输入键',
     'start-font-size')
-_MSG_PAIR_INPUT_DEVICE = test_ui.MakeLabel(
-    'Pairing to input device now...',
-    u'配对到蓝牙输入设备...',
-    'start-font-size')
-_MSG_UNPAIR = test_ui.MakeLabel(
-    'Press shift-p-a-i-r simultaneously on the base.',
-    u'请在在测试键盘上同时按住 shift-p-a-i-r',
-    'start-font-size')
-_MSG_CONNECT_INPUT_DEVICE = test_ui.MakeLabel(
-    'Connecting to input device now...',
-    u'连接到蓝牙输入设备...',
-    'start-font-size')
-_MSG_TEST_INPUT = test_ui.MakeLabel(
+_MSG_PAIR_INPUT_DEVICE = i18n_test_ui.MakeI18nLabelWithClass(
+    'Pairing to input device now...', 'start-font-size')
+_MSG_UNPAIR = i18n_test_ui.MakeI18nLabelWithClass(
+    'Press shift-p-a-i-r simultaneously on the base.', 'start-font-size')
+_MSG_CONNECT_INPUT_DEVICE = i18n_test_ui.MakeI18nLabelWithClass(
+    'Connecting to input device now...', 'start-font-size')
+_MSG_TEST_INPUT = i18n_test_ui.MakeI18nLabelWithClass(
     'Please test input. Press Escape to fail and Enter to pass',
-    u'请测试输入, 如果失败, 请按Esc键,如果成功,请按Enter键',
     'start-font-size')
-_MSG_UNPAIRING = test_ui.MakeLabel('Unpairing', u'取消配对', 'start-font-size')
-_MSG_AUTH_FAILED = test_ui.MakeLabel(
-    'Authentication failed, retrying...',
-    u'验证失败,重试', 'start-font-size')
+_MSG_UNPAIRING = i18n_test_ui.MakeI18nLabelWithClass(
+    'Unpairing', 'start-font-size')
+_MSG_AUTH_FAILED = i18n_test_ui.MakeI18nLabelWithClass(
+    'Authentication failed, retrying...', 'start-font-size')
 
 
 INPUT_MAX_RETRY_TIMES = 10
@@ -148,10 +121,10 @@
 
 def MakePasskeyLabelPrompt(passkey):
   """Creates a label prompting the operator to enter a passkey"""
-  return test_ui.MakeLabel(
-      'Enter passkey %s then press enter on the base.' % passkey,
-      u'按 %s 再按回车' % passkey,
-      'start-font-size')
+  return i18n_test_ui.MakeI18nLabelWithClass(
+      'Enter passkey {key} then press enter on the base.',
+      'start-font-size',
+      key=passkey)
 
 
 def CheckInputCount():
@@ -250,8 +223,8 @@
   target_result = sync_utils.Retry(max_retry_times, retry_interval,
                                    _UpdateProgressBar, target, *args, **kwargs)
   template.SetProgressBarValue(100)
-  log_msg = ('%s was done.' if target_result else '%s failed.') % action_string
-  logging.info(log_msg)
+  log_msg = '%s was done.' if target_result else '%s failed.'
+  logging.info(log_msg, action_string)
   return target_result
 
 
@@ -533,8 +506,7 @@
 
     rssis = []
     for i in xrange(1, 1 + self._scan_counts):
-      label = test_ui.MakeLabel(*[m % (i, self._scan_counts) if '%' in m else m
-                                  for m in _RAW_MSG_DETECT_RSSI])
+      label = _MSG_DETECT_RSSI(i, self._scan_counts)
       self._test.template.SetState(label)
       self._scan_rssi_event.clear()
       self._progress_thread = SetAndStartScanProgressBar(self._test.template,
@@ -1169,8 +1141,8 @@
     self._strongest_rssi_mac = None
     self.fixture = None
     if self.args.input_device_mac_key:
-      self._input_device_mac = \
-        ColonizeMac(factory.get_shared_data(self.args.input_device_mac_key))
+      self._input_device_mac = (
+          ColonizeMac(factory.get_shared_data(self.args.input_device_mac_key)))
     else:
       self._input_device_mac = self.args.input_device_mac
 
diff --git a/py/test/pytests/brightness/brightness.py b/py/test/pytests/brightness/brightness.py
index bd69207..c7b6707 100644
--- a/py/test/pytests/brightness/brightness.py
+++ b/py/test/pytests/brightness/brightness.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright 2016 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -11,6 +9,8 @@
 
 import factory_common  # pylint: disable=unused-import
 from cros.factory.device import device_utils
+from cros.factory.test.i18n import arg_utils as i18n_arg_utils
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
@@ -18,13 +18,10 @@
 
 
 _MSG_CSS_CLASS = 'brightness-test-info'
-_MSG_PASS_FAIL_PROMPT = test_ui.MakeLabel(
-    '</br>Press ENTER to pass, or ESC to fail.',
-    u'</br>测试正常请按 ENTER ,不正常请按 ESC',
-    _MSG_CSS_CLASS)
-_MSG_TIME_REMAINING = (
-    'Time remaining: %d',
-    u'剩余时间:%d')
+_MSG_PASS_FAIL_PROMPT = i18n_test_ui.MakeI18nLabelWithClass(
+    '<br>Press ENTER to pass, or ESC to fail.', _MSG_CSS_CLASS)
+_MSG_TIME_REMAINING = lambda time: i18n_test_ui.MakeI18nLabelWithClass(
+    'Time remaining: {time}', _MSG_CSS_CLASS, time=time)
 
 _ID_PROMPT = 'brightness-test-prompt'
 _ID_COUNTDOWN_TIMER = 'brightness-test-timer'
@@ -35,25 +32,23 @@
 
 
 class BrightnessTest(unittest.TestCase):
-  ARGS = [
+  ARGS = i18n_arg_utils.BackwardCompatibleI18nArgs('msg', 'Message HTML') + [
       Arg('timeout_secs', int, 'Timeout value for the test in seconds.',
           default=10),
-      Arg('msg_en', str, 'Message (HTML in English)'),
-      Arg('msg_zh', (str, unicode), 'Message (HTML in Chinese)',
-          optional=True),
       Arg('levels', (tuple, list), 'A sequence of brightness levels.'),
       Arg('interval_secs', (int, float),
           'Time for each brightness level in seconds.')]
 
   def setUp(self):
+    i18n_arg_utils.ParseArg(self, 'msg')
     self.dut = device_utils.CreateDUTInterface()
     self.ui = test_ui.UI()
     self.template = ui_templates.OneSection(self.ui)
     self.ui.AppendCSS(_BRIGHTNESS_TEST_DEFAULT_CSS)
     self.ui.BindStandardKeys()
     self.template.SetState(_HTML_BRIGHTNESS_TEST)
-    self.ui.SetHTML(test_ui.MakeLabel(self.args.msg_en, self.args.msg_zh,
-                                      _MSG_CSS_CLASS), id=_ID_PROMPT)
+    self.ui.SetHTML(i18n_test_ui.MakeI18nLabelWithClass(
+        self.args.msg, _MSG_CSS_CLASS), id=_ID_PROMPT)
     self.ui.SetHTML(_MSG_PASS_FAIL_PROMPT, append=True, id=_ID_PROMPT)
     process_utils.StartDaemonThread(target=self._BrightnessChangeLoop)
     process_utils.StartDaemonThread(target=self._CountdownTimer)
@@ -78,9 +73,7 @@
     """Starts a countdown timer and fails the test if timer reaches zero."""
     time_remaining = self.args.timeout_secs
     while time_remaining > 0:
-      label = test_ui.MakeLabel(_MSG_TIME_REMAINING[0] % time_remaining,
-                                _MSG_TIME_REMAINING[1] % time_remaining,
-                                _MSG_CSS_CLASS)
+      label = _MSG_TIME_REMAINING(time_remaining)
       self.ui.SetHTML(label, id=_ID_COUNTDOWN_TIMER)
       time.sleep(1)
       time_remaining -= 1
diff --git a/py/test/pytests/brightness/lcd_backlight.py b/py/test/pytests/brightness/lcd_backlight.py
index 90f9ded..627ded4 100644
--- a/py/test/pytests/brightness/lcd_backlight.py
+++ b/py/test/pytests/brightness/lcd_backlight.py
@@ -8,24 +8,27 @@
 """
 
 import factory_common  # pylint: disable=unused-import
+from cros.factory.test.i18n import _
+from cros.factory.test.i18n import arg_utils as i18n_arg_utils
 from cros.factory.test.pytests.brightness import brightness
 from cros.factory.utils import arg_utils
 from cros.factory.utils.arg_utils import Arg
 
 
 class LCDBacklightTest(brightness.BrightnessTest):
-  ARGS = arg_utils.MergeArgs(brightness.BrightnessTest.ARGS, [
-      Arg('msg_en', str, 'Message (HTML in English)',
-          default='Please check if backlight brightness is changing from '
-          'dark to bright.'),
-      Arg('msg_zh', (str, unicode), 'Message (HTML in Chinese)',
-          default=u'请检查萤幕亮度是否由暗变亮'),
-      Arg('levels', (tuple, list), 'A sequence of brightness levels.',
-          optional=True),
-      Arg('interval_secs', (int, float),
-          'Time for each brightness level in seconds.', default=0.5)])
+  ARGS = arg_utils.MergeArgs(
+      brightness.BrightnessTest.ARGS,
+      i18n_arg_utils.BackwardCompatibleI18nArgs(
+          'msg', 'Message HTML',
+          default=_('Please check if backlight brightness is changing from '
+                    'dark to bright.')) +
+      [Arg('levels', (tuple, list), 'A sequence of brightness levels.',
+           optional=True),
+       Arg('interval_secs', (int, float),
+           'Time for each brightness level in seconds.', default=0.5)])
 
   def setUp(self):
+    i18n_arg_utils.ParseArg(self, 'msg')
     if self.args.levels is None:
       self.args.levels = [0.2, 0.4, 0.6, 0.8, 1.0]
     super(LCDBacklightTest, self).setUp()
diff --git a/py/test/pytests/button.py b/py/test/pytests/button.py
index e12a5c0..4a90604 100644
--- a/py/test/pytests/button.py
+++ b/py/test/pytests/button.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright 2014 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -29,6 +27,8 @@
 from cros.factory.test import countdown_timer
 from cros.factory.test import event_log
 from cros.factory.test.fixture import bft_fixture
+from cros.factory.test.i18n import arg_utils as i18n_arg_utils
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
@@ -38,8 +38,16 @@
 _DEFAULT_TIMEOUT = 30
 
 _MSG_PROMPT_CSS_CLASS = 'button-test-info'
-_MSG_PROMPT_PRESS = ('Press the %s button%s', u'按下%s按钮%s')
-_MSG_PROMPT_RELEASE = ('Release the button', u'松开按钮')
+_MSG_PROMPT_PRESS = lambda name, count, total: (
+    i18n_test_ui.MakeI18nLabelWithClass(
+        'Press the {name} button', _MSG_PROMPT_CSS_CLASS,
+        name=name)
+    if total == 1
+    else i18n_test_ui.MakeI18nLabelWithClass(
+        'Press the {name} button ({count}/{total})', _MSG_PROMPT_CSS_CLASS,
+        name=name, count=count, total=total))
+_MSG_PROMPT_RELEASE = i18n_test_ui.MakeI18nLabelWithClass(
+    'Release the button', _MSG_PROMPT_CSS_CLASS)
 
 _ID_PROMPT = 'button-test-prompt'
 _ID_COUNTDOWN_TIMER = 'button-test-timer'
@@ -157,26 +165,24 @@
 
 class ButtonTest(unittest.TestCase):
   """Button factory test."""
-  ARGS = [
+  ARGS = ([
       Arg('timeout_secs', int, 'Timeout value for the test.',
           default=_DEFAULT_TIMEOUT),
       Arg('button_key_name', str, 'Button key name for evdev.',
           optional=False),
       Arg('event_id', int, 'Event ID for evdev. None for auto probe.',
           default=None, optional=True),
-      Arg('button_name_en', (str, unicode),
-          'The name of the button in English.', optional=False),
-      Arg('button_name_zh', (str, unicode),
-          'The name of the button in Chinese.', optional=False),
       Arg('repeat_times', int, 'Number of press/release cycles to test',
           default=1),
       Arg('bft_fixture', dict, bft_fixture.TEST_ARG_HELP,
           default=None, optional=True),
       Arg('bft_button_name', str, 'Button name for BFT fixture',
           default=None, optional=True),
-      ]
+      ] + i18n_arg_utils.BackwardCompatibleI18nArgs(
+          'button_name', 'The name of the button.'))
 
   def setUp(self):
+    i18n_arg_utils.ParseArg(self, 'button_name')
     self.dut = device_utils.CreateDUTInterface()
     self.ui = test_ui.UI()
     self.template = ui_templates.OneSection(self.ui)
@@ -252,24 +258,15 @@
 
   def _MonitorButtonEvent(self):
     for done in xrange(self.args.repeat_times):
-      if self.args.repeat_times == 1:
-        progress = ''
-      else:
-        progress = ' (%d/%d)' % (done, self.args.repeat_times)
-      label = test_ui.MakeLabel(
-          _MSG_PROMPT_PRESS[0] % (self.args.button_name_en, progress),
-          _MSG_PROMPT_PRESS[1] % (self.args.button_name_zh, progress),
-          _MSG_PROMPT_CSS_CLASS)
+      label = _MSG_PROMPT_PRESS(
+          self.args.button_name, done, self.args.repeat_times)
       self.ui.SetHTML(label, id=_ID_PROMPT)
 
       if self._fixture:
         self._fixture.SimulateButtonPress(self.args.bft_button_name, 0)
 
       self._PollForCondition(self.button.IsPressed, 'WaitForPress')
-      label = test_ui.MakeLabel(_MSG_PROMPT_RELEASE[0],
-                                _MSG_PROMPT_RELEASE[1],
-                                _MSG_PROMPT_CSS_CLASS)
-      self.ui.SetHTML(label, id=_ID_PROMPT)
+      self.ui.SetHTML(_MSG_PROMPT_RELEASE, id=_ID_PROMPT)
 
       if self._fixture:
         self._fixture.SimulateButtonRelease(self.args.bft_button_name)
diff --git a/py/test/pytests/buzzer.py b/py/test/pytests/buzzer.py
index d8db926..f041b76 100644
--- a/py/test/pytests/buzzer.py
+++ b/py/test/pytests/buzzer.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -11,26 +9,22 @@
 import unittest
 
 import factory_common  # pylint: disable=unused-import
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 from cros.factory.utils import process_utils
 
-_MSG_BUZZER_INFO = test_ui.MakeLabel(
+_MSG_BUZZER_INFO = i18n_test_ui.MakeI18nLabelWithClass(
     'How many beeps do you hear? <br>'
     'Press space to start.',
-    zh='你听到几声哔声?<br>'
-    '压下空白键开始测试',
-    css_class='buzzer-test-info')
+    'buzzer-test-info')
 
-_MSG_BUZZER_TEST = test_ui.MakeLabel(
+_MSG_BUZZER_TEST = i18n_test_ui.MakeI18nLabelWithClass(
     'How many beeps do you hear? <br>'
     'Press the number you hear to pass the test.<br>'
-    'Press \'r\' to play again.',
-    zh='你听到几声哔声?<br>'
-    '请按下数字代表你听到几声哔声<br>'
-    '按下 \'r\' 重播',
-    css_class='buzzer-test-info')
+    "Press 'r' to play again.",
+    'buzzer-test-info')
 
 _HTML_BUZZER = """
 <table style="width: 70%%; margin: auto;">
diff --git a/py/test/pytests/call_shopfloor.py b/py/test/pytests/call_shopfloor.py
index e039894..f9c6b2f 100644
--- a/py/test/pytests/call_shopfloor.py
+++ b/py/test/pytests/call_shopfloor.py
@@ -1,4 +1,3 @@
-# -*- mode: python; coding: utf-8 -*-
 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -19,6 +18,7 @@
 import factory_common  # pylint: disable=unused-import
 from cros.factory.test import event_log
 from cros.factory.test import factory
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test.rules import privacy
 from cros.factory.test import shopfloor
 from cros.factory.test import test_ui
@@ -126,16 +126,11 @@
 
       def HandleError(trace):
         template.SetState(
-            test_ui.MakeLabel('Shop floor exception:',
-                              'Shop floor 错误:',
-                              'test-status-failed large') +
-            '<p>' +
-            test_ui.Escape(trace) +
-            '<p><br>' +
-            """<button onclick="test.sendTestEvent('retry')">""" +
-            test_ui.MakeLabel('Retry', '重试') +
-            '</button>'
-        )
+            i18n_test_ui.MakeI18nLabelWithClass(
+                'Shop floor exception:',
+                'test-status-failed large') + '<p>' + test_ui.Escape(trace) +
+            '<p><br>' + """<button onclick="test.sendTestEvent('retry')">""" +
+            i18n_test_ui.MakeI18nLabel('Retry') + '</button>')
         process_utils.WaitEvent(self.event)
         self.event.clear()
 
diff --git a/py/test/pytests/camera.py b/py/test/pytests/camera.py
index 4fff628..3ddd756 100644
--- a/py/test/pytests/camera.py
+++ b/py/test/pytests/camera.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -88,6 +86,7 @@
 from cros.factory.device import device_utils
 from cros.factory.test import factory_task
 from cros.factory.test.fixture.camera import barcode
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
@@ -98,41 +97,26 @@
 from cros.factory.external import cv2
 
 
-_MSG_CAMERA_MANUAL_CAPTURE = test_ui.MakeLabel(
-    'Capturing image...',
-    zh=u'拍照中...',
-    css_class='camera-test-info')
-_MSG_CAMERA_MANUAL_TEST = test_ui.MakeLabel(
-    'Press ENTER to pass or ESC to fail.',
-    zh=u'摄像头运作正常请按 ENTER,不正常请按 ESC',
-    css_class='camera-test-info')
-_MSG_CAMERA_TIMEOUT_TEST = test_ui.MakeLabel(
-    'Running the camera until timeout.',
-    zh=u'运行相机直到超时',
-    css_class='camera-test-info')
-_MSG_CAMERA_FRAME_COUNT_TEST = test_ui.MakeLabel(
+_MSG_CAMERA_MANUAL_CAPTURE = i18n_test_ui.MakeI18nLabelWithClass(
+    'Capturing image...', 'camera-test-info')
+_MSG_CAMERA_MANUAL_TEST = i18n_test_ui.MakeI18nLabelWithClass(
+    'Press ENTER to pass or ESC to fail.', 'camera-test-info')
+_MSG_CAMERA_TIMEOUT_TEST = i18n_test_ui.MakeI18nLabelWithClass(
+    'Running the camera until timeout.', 'camera-test-info')
+_MSG_CAMERA_FRAME_COUNT_TEST = i18n_test_ui.MakeI18nLabelWithClass(
     'Running the camera until expected number of frames captured.',
-    zh=u'运行相机直到给订数量',
-    css_class='camera-test-info')
-_MSG_CAMERA_QR_SCAN = test_ui.MakeLabel(
-    'Scanning QR code...',
-    zh=u'侦测 QR 码中...',
-    css_class='camera-test-info')
-_MSG_CAMERA_QR_FOUND_STRING = lambda t: test_ui.MakeLabel(
-    'Scanned QR code: "%s"' % t,
-    zh=u'已侦测 QR 码: "%s"' % t,
-    css_class='camera-test-info')
-_MSG_CAMERA_FACIAL_RECOGNITION = test_ui.MakeLabel(
-    'Detecting faces...',
-    zh=u'侦测人脸中...',
-    css_class='camera-test-info')
-_MSG_LED_TEST = test_ui.MakeLabel(
+    'camera-test-info')
+_MSG_CAMERA_QR_SCAN = i18n_test_ui.MakeI18nLabelWithClass(
+    'Scanning QR code...', 'camera-test-info')
+_MSG_CAMERA_QR_FOUND_STRING = lambda text: i18n_test_ui.MakeI18nLabelWithClass(
+    'Scanned QR code: "{text}"', 'camera-test-info', text=text)
+_MSG_CAMERA_FACIAL_RECOGNITION = i18n_test_ui.MakeI18nLabelWithClass(
+    'Detecting faces...', 'camera-test-info')
+_MSG_LED_TEST = i18n_test_ui.MakeI18nLabelWithClass(
     'Press 0 if LED is flickering, 1 if LED is constantly lit,'
-    '<br/>or ESC to fail.',
-    zh=u'LED 闪烁请按 0,一直亮着请按 1,没亮请按 ESC',
-    css_class='camera-test-info')
-_MSG_TIME_REMAINING = lambda t: test_ui.MakeLabel(
-    'Time remaining: %d' % t, u'剩余时间:%d' % t, 'camera-test-info')
+    '<br>or ESC to fail.', 'camera-test-info')
+_MSG_TIME_REMAINING = lambda time: i18n_test_ui.MakeI18nLabelWithClass(
+    'Time remaining: {time}', 'camera-test-info', time=time)
 
 _ID_IMAGE = 'camera-test-image'
 _ID_PROMPT = 'camera-test-prompt'
diff --git a/py/test/pytests/camera_fixture.py b/py/test/pytests/camera_fixture.py
index 2021d30..127dadc 100644
--- a/py/test/pytests/camera_fixture.py
+++ b/py/test/pytests/camera_fixture.py
@@ -1,4 +1,3 @@
-# -*- mode: python; coding: utf-8 -*-
 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -187,7 +186,8 @@
 
 import ast
 import base64
-from collections import namedtuple, OrderedDict
+from collections import namedtuple
+from collections import OrderedDict
 try:
   import cv2  # pylint: disable=import-error
 except ImportError:
@@ -213,6 +213,9 @@
 from cros.factory.test.fixture.camera import perf_tester as camperf
 from cros.factory.test.fixture.camera import renderer as renderer
 from cros.factory.test.fixture import fixture_connection
+from cros.factory.test import i18n
+from cros.factory.test.i18n import _
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import leds
 from cros.factory.test import network
 from cros.factory.test import shopfloor
@@ -270,34 +273,30 @@
 
 
 # Text labels.
-MSG_TITLE_CALIBRATION = test_ui.MakeLabel(
-    'Camera Fixture Calibration', u'相机制具校正')
-MSG_TITLE_LENS_SHADING_TEST = test_ui.MakeLabel(
-    'Camera Lens Shading Test', u'相机镜头黑点测试')
-MSG_TITLE_IQ_TEST = test_ui.MakeLabel(
-    'Camera Image Quality Test', u'相机影像品质测试')
-MSG_TITLE_ALS_TEST = test_ui.MakeLabel(
-    'ALS Sensor Calibration', u'光感应器校正')
+MSG_TITLE_CALIBRATION = i18n_test_ui.MakeI18nLabel('Camera Fixture Calibration')
+MSG_TITLE_LENS_SHADING_TEST = i18n_test_ui.MakeI18nLabel(
+    'Camera Lens Shading Test')
+MSG_TITLE_IQ_TEST = i18n_test_ui.MakeI18nLabel('Camera Image Quality Test')
+MSG_TITLE_ALS_TEST = i18n_test_ui.MakeI18nLabel('ALS Sensor Calibration')
 
-# Test stage => (English message, Chinese message).
+# Test stage => message
 MSG_TEST_STATUS = {
-    STAGE00_START: ('Starting the test', u'开始测试'),
-    STAGE10_SN: ('Reading serial number', u'读取序号'),
-    STAGE15_FW: ('Checking firmware version', u'检查韧体版本'),
-    STAGE20_INIT: ('Initializing camera', u'初始化摄像头'),
-    STAGE25_AWB: ('Adjusting white balance', u'白平衡调试'),
-    STAGE30_IMG: ('Reading test image', u'读取测试影像'),
-    STAGE30_ALS_LIGHT1: ('Reading Light1 ALS value', u'读取灯光1 ALS数值'),
-    STAGE40_ALS_LIGHT2: ('Reading Light2 ALS value', u'读取灯光2 ALS数值'),
-    STAGE50_ALS_LIGHT3: ('Reading Light3 ALS value', u'读取灯光3 ALS数值'),
-    STAGE50_VC: ('Locating test pattern', u'定位测试图样'),
-    STAGE60_LS: ('Checking vignetting level', u'检测影像暗角'),
-    STAGE60_ALS_CALCULATION: ('Calculate the ALS line', u'计算ALS结果'),
-    STAGE70_VPD: ('Writing the ALS calibration data to vpd',
-                  u'写入ALS校正结果'),
-    STAGE70_MTF: ('Checking image sharpness', u'检测影像清晰度'),
-    STAGE90_END: ('All tests are complete', u'测试已全部完成'),
-    STAGE100_SAVED: ('Test data saved', u'记录档已写入'),
+    STAGE00_START: _('Starting the test'),
+    STAGE10_SN: _('Reading serial number'),
+    STAGE15_FW: _('Checking firmware version'),
+    STAGE20_INIT: _('Initializing camera'),
+    STAGE25_AWB: _('Adjusting white balance'),
+    STAGE30_IMG: _('Reading test image'),
+    STAGE30_ALS_LIGHT1: _('Reading Light1 ALS value'),
+    STAGE40_ALS_LIGHT2: _('Reading Light2 ALS value'),
+    STAGE50_ALS_LIGHT3: _('Reading Light3 ALS value'),
+    STAGE50_VC: _('Locating test pattern'),
+    STAGE60_LS: _('Checking vignetting level'),
+    STAGE60_ALS_CALCULATION: _('Calculate the ALS line'),
+    STAGE70_VPD: _('Writing the ALS calibration data to vpd'),
+    STAGE70_MTF: _('Checking image sharpness'),
+    STAGE90_END: _('All tests are complete'),
+    STAGE100_SAVED: _('Test data saved'),
 }
 
 
@@ -901,8 +900,8 @@
     Args:
       test_stage: Current test stage.
     """
-    msg, msg_zh = MSG_TEST_STATUS[test_stage]
-    self.delegator.ShowTestStatus(msg, msg_zh)
+    msg = MSG_TEST_STATUS[test_stage]
+    self.delegator.ShowTestStatus(msg)
     self.delegator.ShowProgressBar(self.timing[test_stage])
 
   def _Log(self, text):
@@ -1240,7 +1239,7 @@
           'light chamber.', default=False),
       Arg('assume_chamber_connected', bool, 'Assume chamber is connected on '
           'test startup. This is useful when running fixture-based testing. '
-          'The OP won\'t have to reconnect the fixture everytime.',
+          "The OP won't have to reconnect the fixture everytime.",
           default=False),
       Arg('chamber_conn_params', (dict, str), 'Chamber connection parameters, '
           "either a dict or 'default'", default=None, optional=True),
@@ -1444,7 +1443,7 @@
         else:
           log_msg += 'Incorrect Chart'
 
-        self.ShowTestStatus(msg=log_msg, style=(
+        self.ShowTestStatus(i18n.NoTranslation(log_msg), style=(
             STYLE_PASS if success else STYLE_FAIL))
         logging.info(log_msg)
 
@@ -1502,7 +1501,7 @@
         log_msg = 'PASS: ' if success else 'FAIL: '
         log_msg += 'Remaining %d s. Shading ratio=%.3f ' % (
             remaining_time, ls_ratio)
-        self.ShowTestStatus(msg=log_msg, style=(
+        self.ShowTestStatus(i18n.NoTranslation(log_msg), style=(
             STYLE_PASS if success else STYLE_FAIL))
 
         event = self.PopInternalQueue(wait=False)
@@ -1575,10 +1574,12 @@
           success, fail_cause = delegate.RunTest(input_sn)
 
         if success:
-          self.ShowTestStatus(msg='%s: PASS' % prefix, style=STYLE_PASS)
+          self.ShowTestStatus(i18n.NoTranslation('%s: PASS' % prefix),
+                              style=STYLE_PASS)
         else:
-          self.ShowTestStatus(msg='%s: FAIL %r' % (prefix, fail_cause),
-                              style=STYLE_FAIL)
+          self.ShowTestStatus(
+              i18n.NoTranslation('%s: FAIL %r' % (prefix, fail_cause)),
+              style=STYLE_FAIL)
       elif event.event_type == EventType.EXIT_TEST:
         if success:
           self.ui.Pass()
@@ -1615,15 +1616,14 @@
       except Queue.Empty:
         return None
 
-  def ShowTestStatus(self, msg, msg_zh=None, style=STYLE_INFO):
+  def ShowTestStatus(self, msg, style=STYLE_INFO):
     """Shows test status.
 
     Args:
-      msg: English text.
-      msg_zh: Chinese text.
+      msg: i18n text.
       style: CSS style.
     """
-    label = test_ui.MakeLabel(en=msg, zh=msg_zh, css_class=style)
+    label = i18n_test_ui.MakeI18nLabelWithClass(msg, style)
     self.ui.CallJSFunction('UpdateTextLabel', label, ID_TEST_STATUS)
 
   def ShowImage(self, img, html_id):
diff --git a/py/test/pytests/cellular_switch_firmware.py b/py/test/pytests/cellular_switch_firmware.py
index 786dac1..7f042b9 100644
--- a/py/test/pytests/cellular_switch_firmware.py
+++ b/py/test/pytests/cellular_switch_firmware.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -12,6 +10,7 @@
 import unittest
 
 import factory_common  # pylint: disable=unused-import
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test.rf import cellular
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
@@ -26,8 +25,9 @@
     ui = test_ui.UI()
     ui.Run(blocking=False)
     template = ui_templates.OneSection(ui)
-    template.SetState(test_ui.MakeLabel(
-        'Switching firmware to %r<br>' % self.args.target,
-        '切换数据机至%r韧体' % self.args.target,
-        'status-info'))
+    template.SetState(
+        i18n_test_ui.MakeI18nLabelWithClass(
+            'Switching firmware to {target!r}<br>',
+            'status-info',
+            target=self.args.target))
     cellular.SwitchModemFirmware(self.args.target)
diff --git a/py/test/pytests/chameleon/chameleon.py b/py/test/pytests/chameleon/chameleon.py
index 2e0bae8..e68a01e 100644
--- a/py/test/pytests/chameleon/chameleon.py
+++ b/py/test/pytests/chameleon/chameleon.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright 2014 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -22,6 +20,7 @@
 
 import factory_common  # pylint: disable=unused-import
 from cros.factory.device import device_utils
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import state
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
@@ -180,7 +179,7 @@
                     ('whether to load the reference pattern image; True to '
                      'load the test image in a Chrome window on the external '
                      'display, which may have timing issue to the test caused '
-                     'by Chrome\'s pop-up messages'), default=False),
+                     "by Chrome's pop-up messages"), default=False),
       arg_utils.Arg('ignore_regions', list,
                     ('a list of regions to ignore when comparing captured '
                      'images; each element of the list must be a (x, y, width, '
@@ -204,8 +203,8 @@
     self.dut = device_utils.CreateDUTInterface()
     self.ui = test_ui.UI(css=DEFAULT_CSS)
     self.ui_template = ui_templates.OneSection(self.ui)
-    self.ui_template.SetTitle(test_ui.MakeLabel(
-        'Automated External Display Test', zh=u'自动外接显示测试'))
+    self.ui_template.SetTitle(
+        i18n_test_ui.MakeI18nLabel('Automated External Display Test'))
     self.chameleon = Chameleon(
         self.args.chameleon_host, self.args.chameleon_port)
     self.goofy_rpc = state.get_instance()
@@ -259,9 +258,8 @@
         logging.error('Unable to determine the external display to test.')
         self.fail('Please unplug the display to test.')
     elif len(display_info) == 1:
-      self.ui_template.SetState(test_ui.MakeLabel(
-          'Please plug in the display to test',
-          zh=u'请插上待测屏'))
+      self.ui_template.SetState(
+          i18n_test_ui.MakeI18nLabel('Please plug in the display to test'))
       logging.info('Checking %s physical port on Chameleon...', chameleon_port)
       sync_utils.WaitFor(
           lambda: self.chameleon.IsPhysicallyPlugged(chameleon_port),
@@ -365,11 +363,12 @@
     logging.info(
         ('Testing DUT %s port on Chameleon %s port using mode %s...'),
         dut_port, chameleon_port, mode)
-    self.ui_template.SetState(test_ui.MakeLabel(
-        'Testing DUT %s port on Chameleon %s port using mode %s...' %
-        (dut_port, chameleon_port, mode),
-        zh=u'测试 DUT %s 对 Chameleon %s 外接显示 mode: %s...' %
-        (dut_port, chameleon_port, mode)))
+    self.ui_template.SetState(i18n_test_ui.MakeI18nLabel(
+        'Testing DUT {dut_port} port on Chameleon {chameleon_port} port'
+        ' using mode {mode}...',
+        dut_port=dut_port,
+        chameleon_port=chameleon_port,
+        mode=mode))
 
     if not mode in EDIDS[chameleon_port]:
       self.fail('Invalid mode for %s: %s' % (chameleon_port, mode))
@@ -380,11 +379,10 @@
     with self.chameleon.PortEdid(chameleon_port, edid):
       original_display, external_display = self.ProbeDisplay(chameleon_port)
 
-      self.ui_template.SetState(test_ui.MakeLabel(
-          'Automated testing on %s to %s in progress...' %
-          (dut_port, chameleon_port),
-          zh=u'%s 对 %s 自动测试进行中...' %
-          (dut_port, chameleon_port)))
+      self.ui_template.SetState(i18n_test_ui.MakeI18nLabel(
+          'Automated testing on {dut_port} to {chameleon_port} in progress...',
+          dut_port=dut_port,
+          chameleon_port=chameleon_port))
 
       if self.args.load_test_image:
         with self.NewWindow(
@@ -413,10 +411,9 @@
     pixel_diff_margin = 1 if self.args.downscale_to_tv_level else 0
     if sum(histogram[pixel_diff_margin + 1:]) > 0:
       self.ui_template.SetState(
-          test_ui.MakeLabel(
-              'Captured images mismatch', zh=u'撷取的图片不相符') +
-          ('</br></br>'
-           '<image src="%s" width=%d height=%d></image>') %
+          i18n_test_ui.MakeI18nLabel('Captured images mismatch') +
+          '<br><br>' +
+          '<image src="%s" width=%d height=%d></image>' %
           (self.ui.URLForFile(self.DIFF_IMAGE_PATH),
            original_display['workArea']['width'] * self.UI_IMAGE_RESIZE_RATIO,
            original_display['workArea']['height'] * self.UI_IMAGE_RESIZE_RATIO))
diff --git a/py/test/pytests/charger.py b/py/test/pytests/charger.py
index 10f6d63..3ab34e2 100644
--- a/py/test/pytests/charger.py
+++ b/py/test/pytests/charger.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -19,12 +17,14 @@
 from cros.factory.device import device_utils
 from cros.factory.test import event_log
 from cros.factory.test import factory
+from cros.factory.test.i18n import _
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.test.utils import stress_manager
 from cros.factory.utils.arg_utils import Arg
 
-_TEST_TITLE = test_ui.MakeLabel('Charger Test', u'充電放電測試')
+_TEST_TITLE = i18n_test_ui.MakeI18nLabel('Charger Test')
 
 
 def _REGULATE_CHARGE_TEXT(charge, target, timeout, load,
@@ -43,15 +43,15 @@
     A html label to show in test ui.
   """
   unit = '%' if use_percentage else 'mAh'
-  return test_ui.MakeLabel(
-      ('Discharging' if charge > target else 'Charging') +
-      ' to %.2f%s (Current charge: %.2f%s, battery current: %d mA) under load '
-      '%d.<br>Time remaining: %d sec.' %
-      (target, unit, charge, unit, battery_current, load, timeout),
-      (u'放電' if charge > target else u'充電') +
-      u'至 %.2f%s (目前電量為 %.2f%s, 電池電流 %d mA)'
-      u'負載 %d.<br>剩餘時間: %d 秒.' %
-      (target, unit, charge, unit, battery_current, load, timeout))
+  action = _('Discharging') if charge > target else _('Charging')
+  return i18n_test_ui.MakeI18nLabel(
+      '{action} to {target:.2f}{unit} '
+      '(Current charge: {charge:.2f}{unit},'
+      ' battery current: {battery_current} mA)'
+      ' under load {load}.<br>'
+      'Time remaining: {timeout} sec.',
+      action=action, target=target, unit=unit, charge=charge,
+      battery_current=battery_current, load=load, timeout=timeout)
 
 
 def _MEET_TEXT(target, use_percentage):
@@ -65,11 +65,12 @@
     A html label to show in test ui.
   """
   unit = '%' if use_percentage else 'mAh'
-  return test_ui.MakeLabel('OK! Meet %.2f%s' % (target, unit),
-                           u'OK! 達到 %.2f%s' % (target, unit))
+  return i18n_test_ui.MakeI18nLabel(
+      'OK! Meet {target:.2f}{unit}', target=target, unit=unit)
 
-_CHARGE_TEXT = test_ui.MakeLabel('Testing charger', u'測試充電中')
-_DISCHARGE_TEXT = test_ui.MakeLabel('Testing discharge', u'測試放電中')
+
+_CHARGE_TEXT = i18n_test_ui.MakeI18nLabel('Testing charger')
+_DISCHARGE_TEXT = i18n_test_ui.MakeI18nLabel('Testing discharge')
 
 Spec = namedtuple('Spec', 'charge_change timeout_secs load')
 
diff --git a/py/test/pytests/check_image_version.py b/py/test/pytests/check_image_version.py
index ea6e24e..40d41b5 100644
--- a/py/test/pytests/check_image_version.py
+++ b/py/test/pytests/check_image_version.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -19,6 +17,7 @@
 from cros.factory.test.event_log import Log
 from cros.factory.test import factory
 from cros.factory.test import factory_task
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import shopfloor
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
@@ -30,7 +29,7 @@
 from cros.factory.utils import debug_utils
 
 
-_TEST_TITLE = test_ui.MakeLabel('Check Image Version', u'检查映像版本')
+_TEST_TITLE = i18n_test_ui.MakeI18nLabel('Check Image Version')
 
 _CSS = """
 .start-font-size {
@@ -39,23 +38,15 @@
 """
 
 # Messages for tasks
-_MSG_VERSION_MISMATCH = test_ui.MakeLabel(
+_MSG_VERSION_MISMATCH = i18n_test_ui.MakeI18nLabelWithClass(
     'Factory image version is incorrect. Please re-image this device.',
-    u'映像版本不正确,请重新安装。',
     'start-font-size test-error')
-_MSG_NETWORK = test_ui.MakeLabel(
-    'Please connect to ethernet.',
-    u'请连接到以太网。')
-_MSG_NETBOOT = test_ui.MakeLabel(
-    'Factory image version is incorrect. Press space to re-image.',
-    u'映像版本不正确,请按空白键重新安装。')
-_MSG_REIMAGING = test_ui.MakeLabel(
-    'Flashing netboot firmware...',
-    u'烧录网路开机固件...')
-_MSG_FLASH_ERROR = test_ui.MakeLabel(
-    'Error flashing netboot firmware!',
-    u'烧录网路开机固件失败',
-    'start-font-size test-error')
+_MSG_NETWORK = i18n_test_ui.MakeI18nLabel('Please connect to ethernet.')
+_MSG_NETBOOT = i18n_test_ui.MakeI18nLabel(
+    'Factory image version is incorrect. Press space to re-image.')
+_MSG_REIMAGING = i18n_test_ui.MakeI18nLabel('Flashing netboot firmware...')
+_MSG_FLASH_ERROR = i18n_test_ui.MakeI18nLabelWithClass(
+    'Error flashing netboot firmware!', 'start-font-size test-error')
 
 _LSB_RELEASE_PATH = '/etc/lsb-release'
 
diff --git a/py/test/pytests/check_wifi_calibration.py b/py/test/pytests/check_wifi_calibration.py
index 839a500..9bb78ae 100644
--- a/py/test/pytests/check_wifi_calibration.py
+++ b/py/test/pytests/check_wifi_calibration.py
@@ -1,4 +1,3 @@
-# -*- mode: python; coding: utf-8 -*-
 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -19,6 +18,7 @@
 import factory_common  # pylint: disable=unused-import
 from cros.factory.test import event_log
 from cros.factory.test import factory
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
@@ -147,8 +147,8 @@
 
     ui = test_ui.UI()
     template = ui_templates.OneSection(ui)
-    template.SetTitle(test_ui.MakeLabel(
-        "Calibration data doesn't meet requirement"))
+    template.SetTitle(
+        i18n_test_ui.MakeI18nLabel("Calibration data doesn't meet requirement"))
     template.SetState(
         '<div class=test-status-failed '
         'style="font-size: 100%; white-space: pre-wrap">' +
diff --git a/py/test/pytests/compass.py b/py/test/pytests/compass.py
index b3e950c..1619a59 100644
--- a/py/test/pytests/compass.py
+++ b/py/test/pytests/compass.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 # Copyright 2017 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -14,12 +13,14 @@
 import factory_common  # pylint: disable=unused-import
 from cros.factory.device import device_utils
 from cros.factory.test import factory
+from cros.factory.test.i18n import _
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
-from cros.factory.utils import sync_utils
 from cros.factory.utils.arg_utils import Arg
+from cros.factory.utils import sync_utils
 
-_COMPASS_CSS = '''
+_COMPASS_CSS = """
 .compass {
   width: 300px;
   height: 300px;
@@ -34,9 +35,9 @@
   background: #afa;
   font-size: 4em;
 }
-'''
+"""
 
-_STATE_TEMPLATE = '''
+_STATE_TEMPLATE = """
 <div>
   <div style='position: absolute; text-align: left'>
     in_magn_x: {in_magn_x}<br>
@@ -49,10 +50,9 @@
     <div style='position: absolute; bottom: 0; width: 300px'>S</div>
   </div>
 <div>
-'''
+"""
 
-_MSG_STATUS_SUCCESS = test_ui.MakeLabel(
-    'Success!', u'成功!')
+_MSG_STATUS_SUCCESS = i18n_test_ui.MakeI18nLabel('Success!')
 _HTML_STATUS_SUCCESS = '<div class="success">%s</div>' % _MSG_STATUS_SUCCESS
 
 _NORTH = (0, 1)
@@ -75,7 +75,7 @@
     self._template = ui_templates.TwoSections(self.ui)
 
   def runTest(self):
-    self._SetInstruction('north', u'北')
+    self._SetInstruction(_('north'))
     sync_utils.PollForCondition(
         poll_method=lambda: self._CheckDirection(_NORTH),
         timeout_secs=1000,
@@ -83,7 +83,7 @@
     self._template.SetState(_HTML_STATUS_SUCCESS)
     time.sleep(_FLASH_STATUS_TIME)
 
-    self._SetInstruction('south', u'南')
+    self._SetInstruction(_('south'))
     sync_utils.PollForCondition(
         poll_method=lambda: self._CheckDirection(_SOUTH),
         timeout_secs=1000,
@@ -91,9 +91,9 @@
     self._template.SetState(_HTML_STATUS_SUCCESS)
     time.sleep(_FLASH_STATUS_TIME)
 
-  def _SetInstruction(self, direction_en, direction_zh):
-    label = test_ui.MakeLabel('Put the DUT towards %s' % direction_en,
-                              u'将机器朝向%s方' % direction_zh)
+  def _SetInstruction(self, direction):
+    label = i18n_test_ui.MakeI18nLabel(
+        'Put the DUT towards {direction}', direction=direction)
     self._template.SetTitle(label)
 
   def _CalculateDirection(self, x, y):
diff --git a/py/test/pytests/countdown.css b/py/test/pytests/countdown.css
new file mode 100644
index 0000000..795a31a
--- /dev/null
+++ b/py/test/pytests/countdown.css
@@ -0,0 +1,58 @@
+table {
+  margin: auto;
+  border: solid 4px #779FD3;
+  border-spacing: 0;
+}
+th, td {
+  padding: 0 8px;
+}
+thead tr {
+  font-size: 200%;
+  background-color: #CDDFF0;
+}
+thead tr th {
+  text-align: center;
+}
+tbody tr {
+  background-color: white;
+}
+tbody tr:first-child * {
+  padding-top: 4px;
+}
+tbody tr:last-child * {
+  padding-bottom: 4px;
+}
+.float-right {
+  float: right;
+}
+.cd-log, .cd-legend {
+  margin-top: 10px;
+  margin-left: auto;
+  margin-right: auto;
+  border: solid 4px #779FD3;
+  background-color: white;
+  text-align: left;
+  width: 80%;
+}
+.cd-log {
+  height: 50%;
+  overflow: scroll;
+  padding: 10px;
+}
+.cd-legend {
+  display: none;
+}
+.cd-legend-title {
+  font-weight: bold;
+  text-align: center;
+  width: 100%;
+  background-color: #CDDFF0;
+}
+.cd-legend-item-container {
+  padding-left: 5px;
+  padding-right: 5px;
+}
+.cd-legend-item {
+  width: 24%;
+  display: inline-block;
+}
diff --git a/py/test/pytests/countdown.html b/py/test/pytests/countdown.html
deleted file mode 100644
index bee04b0..0000000
--- a/py/test/pytests/countdown.html
+++ /dev/null
@@ -1,109 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-
-<style type="text/css">
-table {
-  margin: auto;
-  border: solid 4px #779FD3;
-  border-spacing: 0;
-}
-th, td {
-  padding: 0 8px;
-}
-thead tr {
-  font-size: 200%;
-  background-color: #CDDFF0;
-}
-thead tr th {
-  text-align: center;
-}
-tbody tr {
-  background-color: white;
-}
-tbody tr:first-child * {
-  padding-top: 4px;
-}
-tbody tr:last-child * {
-  padding-bottom: 4px;
-}
-.float-right {
-  float: right;
-}
-.cd-log, .cd-legend {
-  margin-top: 10px;
-  margin-left: auto;
-  margin-right: auto;
-  border: solid 4px #779FD3;
-  background-color: white;
-  text-align: left;
-  width: 80%;
-}
-.cd-log {
-  height: 50%;
-  overflow: scroll;
-  padding: 10px;
-}
-.cd-legend {
-  display: none;
-}
-.cd-legend-title {
-  font-weight: bold;
-  text-align: center;
-  width: 100%;
-  background-color: #CDDFF0;
-}
-.cd-legend-item-container {
-  padding-left: 5px;
-  padding-right: 5px;
-}
-.cd-legend-item {
-  width: 24%;
-  display: inline-block;
-}
-</style>
-
-<div class="test-vcenter-outer">
-<div class="test-vcenter-inner" id="cd-container">
-
-<table>
-  <thead>
-    <tr>
-      <th colspan=2>
-        <span class='goofy-label-en' id='cd-title-en'></span>
-        <span class='goofy-label-zh' id='cd-title-zh'></span>
-      </th>
-    </tr>
-  </thead>
-  <tbody>
-    <tr>
-      <th>
-        <span class='goofy-label-en'>Elapsed time:</span>
-        <span class='goofy-label-zh'>经过时间:</span>
-      </th>
-      <td id='cd-elapsed-time'>00:00:00</td>
-    </tr>
-    <tr>
-      <th>
-        <span class='goofy-label-en'>Remaining time:</span>
-        <span class='goofy-label-zh'>剩余时间:</span>
-      </th>
-      <td id='cd-remaining-time'>00:00:00</td>
-    </tr>
-    <tr>
-      <th>
-        <span class='goofy-label-en'>Load:</span>
-        <span class='goofy-label-zh'>系统负载:</span>
-      </th>
-      <td id='cd-system-load'></span>
-    </tr>
-  </tbody>
-</table>
-
-<div class='cd-log' id='cd-log-panel'>
-</div>
-<div class='cd-legend' id='cd-legend-panel'>
-  <div class='cd-legend-title'>Temperature Sensor Names</div>
-  <div class='cd-legend-item-container' id='cd-legend-item-panel'></div>
-</div>
-
-</div></div>
diff --git a/py/test/pytests/countdown.py b/py/test/pytests/countdown.py
index d91af39..94e8c88 100644
--- a/py/test/pytests/countdown.py
+++ b/py/test/pytests/countdown.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -18,17 +17,65 @@
 from cros.factory.device import device_utils
 from cros.factory.test import event_log
 from cros.factory.test import factory
+from cros.factory.test.i18n import _
+from cros.factory.test.i18n import arg_utils as i18n_arg_utils
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.utils.arg_utils import Arg
 from cros.factory.utils import time_utils
 
 
+_HTML = ("""
+<div class="test-vcenter-outer">
+<div class="test-vcenter-inner" id="cd-container">
+
+<table>
+  <thead>
+    <tr>
+      <th colspan=2>
+        <span id='cd-title'></span>
+      </th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th>
+""" + i18n_test_ui.MakeI18nLabel('Elapsed time:') + """
+      </th>
+      <td id='cd-elapsed-time'>00:00:00</td>
+    </tr>
+    <tr>
+      <th>
+""" + i18n_test_ui.MakeI18nLabel('Remaining time:') + """
+      </th>
+      <td id='cd-remaining-time'>00:00:00</td>
+    </tr>
+    <tr>
+      <th>
+""" + i18n_test_ui.MakeI18nLabel('Load:') + """
+      </th>
+      <td id='cd-system-load'></span>
+    </tr>
+  </tbody>
+</table>
+
+<div class='cd-log' id='cd-log-panel'>
+</div>
+<div class='cd-legend' id='cd-legend-panel'>
+  <div class='cd-legend-title'>Temperature Sensor Names</div>
+  <div class='cd-legend-item-container' id='cd-legend-item-panel'></div>
+</div>
+
+</div></div>
+""")
+
+
 class CountDownTest(unittest.TestCase):
   """A countdown test that monitors and logs various system status."""
 
-  ARGS = [
-      Arg('title_en', (str, unicode), 'English title.', 'Countdown'),
-      Arg('title_zh', (str, unicode), 'Chinese title.', u'倒數計時'),
+  ARGS = (i18n_arg_utils.BackwardCompatibleI18nArgs(
+      'title', 'title.', default=_('Countdown')
+  ) + [
       Arg('position_top_right', bool,
           'A workaround for some machines on which graphics test would overlay '
           'countdown info.', False),
@@ -53,7 +100,7 @@
           'relation is a text output with warning messages to describe the two '
           'temp sensors in the rule', [], optional=True),
       Arg('fan_min_expected_rpm', int, 'Minimum fan rpm expected', None,
-          optional=True)]
+          optional=True)])
 
   def FormatSeconds(self, secs):
     hours = int(secs / 3600)
@@ -171,17 +218,19 @@
                        self._dut.fan.GetFanRPM())
 
   def setUp(self):
+    i18n_arg_utils.ParseArg(self, 'title')
     self._dut = device_utils.CreateDUTInterface()
     self.Status = collections.namedtuple('Status', ['temperatures', 'fan_rpm'])
 
   def runTest(self):
     # Allow attributes to be defined outside __init__
-    # pylint: disable=W0201
+    # pylint: disable=attribute-defined-outside-init
 
     self._ui = test_ui.UI()
     self._ui.Run(blocking=False)
-    self._ui.SetHTML(self.args.title_en, id='cd-title-en')
-    self._ui.SetHTML(self.args.title_zh, id='cd-title-zh')
+    self._ui.SetHTML(_HTML)
+    self._ui.SetHTML(i18n_test_ui.MakeI18nLabel(self.args.title),
+                     id='cd-title')
 
     # A workaround for some machines in which graphics test would
     # overlay countdown info.
diff --git a/py/test/pytests/developer_switch.py b/py/test/pytests/developer_switch.py
index 46852f8..be0b48e 100644
--- a/py/test/pytests/developer_switch.py
+++ b/py/test/pytests/developer_switch.py
@@ -1,5 +1,4 @@
 #!/usr/bin/env python
-# -*- coding: utf-8 -*-
 # Copyright 2014 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -9,27 +8,24 @@
 import unittest
 
 import factory_common  # pylint: disable=unused-import
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 from cros.factory.utils import process_utils
 from cros.factory.utils import sync_utils
 
-_MSG_TURN_ON = test_ui.MakeLabel(
-    'Please turn <b class="on">ON</b> Developer Switch.',
-    u'请<b class="on">开启</b> DEV SW 开发者开关。')
+_MSG_TURN_ON = i18n_test_ui.MakeI18nLabel(
+    'Please turn <b class="on">ON</b> Developer Switch.')
 
-_MSG_TURN_OFF = test_ui.MakeLabel(
-    'Please turn <b class="off">OFF</b> Developer Switch.',
-    u'请<b class="off">关闭</b> DEV SW 开发者开关。')
+_MSG_TURN_OFF = i18n_test_ui.MakeI18nLabel(
+    'Please turn <b class="off">OFF</b> Developer Switch.')
 
-_MSG_SW_ON = test_ui.MakeLabel(
-    'Develop switch is currently <b class="on">ON</b>.',
-    u'DEV SW 开发者开关目前为<b class="on">开启</b>状态')
+_MSG_SW_ON = i18n_test_ui.MakeI18nLabel(
+    'Develop switch is currently <b class="on">ON</b>.')
 
-_MSG_SW_OFF = test_ui.MakeLabel(
-    'Develop switch is currently <b class="off">OFF</b>.',
-    u'DEV SW 开发者开关目前为<b class="off">关闭</b>状态')
+_MSG_SW_OFF = i18n_test_ui.MakeI18nLabel(
+    'Develop switch is currently <b class="off">OFF</b>.')
 
 _TEST_PAGE_CSS = """
 .on {
diff --git a/py/test/pytests/display_images.py b/py/test/pytests/display_images.py
index a8ec24a..e663d92 100644
--- a/py/test/pytests/display_images.py
+++ b/py/test/pytests/display_images.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 # Copyright 2016 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -27,6 +26,9 @@
 
 import factory_common  # pylint: disable=unused-import
 from cros.factory.device import device_utils
+from cros.factory.test.i18n import _
+from cros.factory.test.i18n import arg_utils as i18n_arg_utils
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
@@ -63,12 +65,9 @@
   border: 1px solid gray;}
 """
 
-_PROMPT = test_ui.MakeLabel(
+_PROMPT = i18n_test_ui.MakeI18nLabel(
     'Press space to show each image on display<br>'
-    'Press Enter to PASS after showing all images',
-    u'按空白键来拨放影像在萤幕上<br>'
-    u'拨放完所有影像后,压下Enter表示成功'
-)
+    'Press Enter to PASS after showing all images')
 
 
 def GetUploadMsg(name, index, total):
@@ -79,8 +78,11 @@
     index: the current index of the file.
     total: total files for uploading.
   """
-  return test_ui.MakeLabel('(%d/%d)Uploading images %s' % (index, total, name),
-                           u'(%d/%d)正在上传图档 %s' % (index, total, name))
+  return i18n_test_ui.MakeI18nLabel(
+      '({index}/{total})Uploading images {name}',
+      index=index,
+      total=total,
+      name=name)
 
 
 def GetThumbImageTableTag(paths):
@@ -116,14 +118,16 @@
     _can_pass: check if operator checks all images.
   """
   ARGS = [
-      Arg('title', tuple, 'Label Title of the test (en, zh)',
-          ('Display', u'显示测试')),
+      i18n_arg_utils.I18nArg(
+          'title', 'Label Title of the test',
+          default=_('Display Test'), accept_tuple=True),
       Arg('compressed_image_file', str, 'Compressed image file name.',
           default=_DEFAULT_IMAGE_FILE)
   ]
 
   def setUp(self):
     """Initializes frontend presentation and properties."""
+    i18n_arg_utils.ParseArg(self, 'title')
     self._dut = device_utils.CreateDUTInterface()
     self._ui = test_ui.UI()
     self._template = ui_templates.OneSection(self._ui)
@@ -131,7 +135,7 @@
     self._ui.AppendCSS(_CSS_DISPLAY)
     self._template.SetState(_HTML_DISPLAY)
     self._ui.SetHTML(
-        test_ui.MakeLabel(self.args.title[0], self.args.title[1]),
+        i18n_test_ui.MakeI18nLabel(self.args.title),
         id='display_title')
     self._ui.SetHTML(_PROMPT, id='prompt')
     self._dut_temp_dir = self._dut.temp.mktemp(True, '', 'display')
diff --git a/py/test/pytests/emmc_check_fw_version.py b/py/test/pytests/emmc_check_fw_version.py
index e4a5ecb..4963d11 100644
--- a/py/test/pytests/emmc_check_fw_version.py
+++ b/py/test/pytests/emmc_check_fw_version.py
@@ -1,4 +1,3 @@
-# -*- mode: python; coding: utf-8 -*-
 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -26,12 +25,13 @@
 
 
 import logging
-import re
 import os
+import re
 import unittest
 
 import factory_common  # pylint: disable=unused-import
 from cros.factory.test import event_log
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
@@ -124,18 +124,14 @@
     if self.args.emmc_updater_available:
       ui = test_ui.UI()
       template = ui_templates.OneSection(ui)
-      template.SetTitle(test_ui.MakeLabel(
-          'eMMC Firmware Version Incorrect',
-          'eMMC 韧体版本不对'))
+      template.SetTitle(
+          i18n_test_ui.MakeI18nLabel('eMMC Firmware Version Incorrect'))
       template.SetState(
-          '<div class=test-status-failed style="font-size: 150%">' +
-          test_ui.MakeLabel(
-              'The eMMC firmware version (%s) is incorrect. '
-              '<br>Please run the eMMC firmware update tool.' % prv,
-
-              'eMMC 韧体版(%s)版本不对。'
-              '<br>必须更新 eMMC 韧体并重新安装工厂测试软件。' % prv) +
-          '</div>')
+          '<div class=test-status-failed style="font-size: 150%">'
+          + i18n_test_ui.MakeI18nLabel(
+              'The eMMC firmware version ({version}) is incorrect. '
+              '<br>Please run the eMMC firmware update tool.',
+              version=prv) + '</div>')
       ui.Run()  # Forever
     else:
       self.fail('The eMMC firmware version (%s) is incorrect. However, no '
diff --git a/py/test/pytests/ethernet.py b/py/test/pytests/ethernet.py
index b616aca..1fa06b7 100644
--- a/py/test/pytests/ethernet.py
+++ b/py/test/pytests/ethernet.py
@@ -1,13 +1,11 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 """A factory test for basic ethernet connectivity."""
 
-import re
 import logging
+import re
 import time
 import unittest
 
@@ -15,17 +13,15 @@
 from cros.factory.device import device_utils
 from cros.factory.test import event as test_event
 from cros.factory.test import factory
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 from cros.factory.utils import net_utils
 
-_MSG_ETHERNET_INFO = test_ui.MakeLabel(
+_MSG_ETHERNET_INFO = i18n_test_ui.MakeI18nLabelWithClass(
     'Please plug ethernet cable into built-in ethernet port<br>'
-    'Press space to start.',
-    zh='请插入网路线到内建网路埠<br>'
-    '压下空白键开始测试',
-    css_class='ethernet-test-info')
+    'Press space to start.', 'ethernet-test-info')
 
 _HTML_ETHERNET = """
 <table style="width: 70%%; margin: auto;">
diff --git a/py/test/pytests/ext_display/ext_display.py b/py/test/pytests/ext_display/ext_display.py
index fce6d5d..5a01d4f 100644
--- a/py/test/pytests/ext_display/ext_display.py
+++ b/py/test/pytests/ext_display/ext_display.py
@@ -15,9 +15,10 @@
         pytest_name='ext_display',
         dargs={
             'display_info': [
-                (test_ui.MakeLabel('Left HDMI External Display',
-                                   u'左边HDMI'),
-                 'HDMI-A-1', None, 0)],
+                (i18n_test_ui.MakeI18nLabel({
+                    'en-US': 'Left HDMI External Display',
+                    'zh-CN': '左边HDMI'}),
+                    'HDMI-A-1', None, 0)],
         })
 """
 
@@ -36,6 +37,7 @@
 from cros.factory.test import factory
 from cros.factory.test import factory_task
 from cros.factory.test.fixture import bft_fixture
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test.pytests import audio
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
@@ -43,8 +45,7 @@
 from cros.factory.utils.arg_utils import Arg
 
 
-_TEST_TITLE = test_ui.MakeLabel('External Display Test',
-                                u'外接显示屏测试')
+_TEST_TITLE = i18n_test_ui.MakeI18nLabel('External Display Test')
 _DIV_CENTER_INSTRUCTION = """
 <div id='instruction-center' class='template-instruction'></div>"""
 _CSS = '#pass_key {font-size:36px; font-weight:bold;}'
@@ -54,43 +55,42 @@
 
 
 # Messages for tasks
-def _GetTitleConnectTest(d):
-  return test_ui.MakeLabel('%s Connect' % d, u'%s 连接' % d)
+def _GetTitleConnectTest(display):
+  return i18n_test_ui.MakeI18nLabel('{display} Connect', display=display)
 
 
-def _GetTitleVideoTest(d):
-  return test_ui.MakeLabel('%s Video' % d, u'%s 视讯' % d)
+def _GetTitleVideoTest(display):
+  return i18n_test_ui.MakeI18nLabel('{display} Video', display=display)
 
 
-def _GetTitleDisconnectTest(d):
-  return test_ui.MakeLabel('%s Disconnect' % d, u'%s 移除' % d)
+def _GetTitleDisconnectTest(display):
+  return i18n_test_ui.MakeI18nLabel('{display} Disconnect', display=display)
 
 
-def _GetMsgConnectTest(d):
-  return test_ui.MakeLabel('Connect external display: %s' % d,
-                           u'请接上外接显示屏: %s' % d)
+def _GetMsgConnectTest(display):
+  return i18n_test_ui.MakeI18nLabel('Connect external display: {display}',
+                                    display=display)
 
 
-def _GetMsgVideoTest(d):
-  return test_ui.MakeLabel('Do you see video on %s?' % d,
-                           u'外接显示屏 %s 是否有画面?' % d)
+def _GetMsgVideoTest(display):
+  return i18n_test_ui.MakeI18nLabel('Do you see video on {display}?',
+                                    display=display)
 
 
-def _GetMsgFixtureVideoTest(d):
-  return test_ui.MakeLabel(
-      'Fixture is checking if video is displayed on %s?' % d,
-      u'治具正在測試外接显示屏 %s 是否有画面?' % d)
+def _GetMsgFixtureVideoTest(display):
+  return i18n_test_ui.MakeI18nLabel(
+      'Fixture is checking if video is displayed on {display}?',
+      display=display)
 
 
-def _GetMsgDisconnectTest(d):
-  return test_ui.MakeLabel('Disconnect external display: %s' % d,
-                           u'移除外接显示屏: %s' % d)
+def _GetMsgDisconnectTest(display):
+  return i18n_test_ui.MakeI18nLabel('Disconnect external display: {display}',
+                                    display=display)
 
 
-def _GetMsgPromptPassKey(k):
-  return test_ui.MakeLabel(
-      'Press <span id="pass_key">%d</span> to pass the test.' % k,
-      u'通过请按 <span id="pass_key">%d</span> 键' % k)
+def _GetMsgPromptPassKey(key):
+  return i18n_test_ui.MakeI18nLabel(
+      'Press <span id="pass_key">{key}</span> to pass the test.', key=key)
 
 
 DISPLAY_INFO_ARG_HELP = """
@@ -562,7 +562,7 @@
   """Main class for external display test."""
   ARGS = [
       Arg('main_display', str,
-          'xrandr/modeprint ID for ChromeBook\'s main display.',
+          "xrandr/modeprint ID for ChromeBook's main display.",
           optional=False),
       Arg('display_info', list, DISPLAY_INFO_ARG_HELP, optional=False),
       Arg('bft_fixture', dict, bft_fixture.TEST_ARG_HELP, default=None,
@@ -627,8 +627,8 @@
           tasks.append(VideoTask(args))
           if args.audio_card:
             tasks.append(AudioSetupTask(self._dut, args.init_actions))
-            audio_label = test_ui.MakeLabel('%s Audio' % args.display_label,
-                                            u' %s 音讯' % args.display_label)
+            audio_label = i18n_test_ui.MakeI18nLabel(
+                '{display_label} Audio', display_label=args.display_label)
             tasks.append(audio.AudioDigitPlaybackTask(
                 self._dut, self._ui, audio_label, 'instruction',
                 'instruction-center', card=args.audio_card,
diff --git a/py/test/pytests/fan_speed.py b/py/test/pytests/fan_speed.py
index b364174..1d2feb7 100644
--- a/py/test/pytests/fan_speed.py
+++ b/py/test/pytests/fan_speed.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -32,13 +30,15 @@
 import factory_common  # pylint: disable=unused-import
 from cros.factory.device import device_utils
 from cros.factory.test import factory
+from cros.factory.test.i18n import _
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 
 
-_TEST_TITLE = test_ui.MakeLabel('Fan Speed Test', zh=u'风扇转速测试')
-_MSG_FAN_SPEED = test_ui.MakeLabel('Fan speed (RPM):', zh=u'风扇转速(RPM):')
+_TEST_TITLE = i18n_test_ui.MakeI18nLabel('Fan Speed Test')
+_MSG_FAN_SPEED = i18n_test_ui.MakeI18nLabel('Fan speed (RPM):')
 _ID_STATUS = 'fs_status'
 _ID_RPM = 'fs_rpm'
 _TEST_BODY = ('<div id="%s"></div><br>\n'
@@ -110,11 +110,15 @@
     fan_count = len(observed_rpm)
     spin_up = target_rpm > _Average(observed_rpm)
 
-    status = 'Spin %s fan speed: %s -> %d RPM.' % (
-        'up' if spin_up else 'down', observed_rpm, target_rpm)
-    status_zh = u'风扇%s速: %s -> %d PRM.' % (
-        u'加' if spin_up else u'减', observed_rpm, target_rpm)
-    self._ui.SetHTML(test_ui.MakeLabel(status, status_zh), id=_ID_STATUS)
+    status = (
+        _('Spin up fan speed: {observed_rpm} -> {target_rpm} RPM.')
+        if spin_up
+        else _('Spin down fan speed: {observed_rpm} -> {target_rpm} RPM.'))
+    self._ui.SetHTML(
+        i18n_test_ui.MakeI18nLabel(status,
+                                   observed_rpm=observed_rpm,
+                                   target_rpm=target_rpm),
+        id=_ID_STATUS)
     self._ui.SetHTML(str(observed_rpm), id=_ID_RPM)
     logging.info(status)
 
@@ -127,7 +131,7 @@
     # probe_interval_secs.
     end_time = time.time() + self.args.duration_secs
     # Samples of all fan speed with sample period: probe_interval_secs.
-    ith_fan_samples = [[] for _ in xrange(fan_count)]
+    ith_fan_samples = [[] for unused_i in xrange(fan_count)]
     while time.time() < end_time:
       observed_rpm = self._fan.GetFanRPM(self.args.fan_id)
       for i, ith_fan_rpm in enumerate(observed_rpm):
diff --git a/py/test/pytests/fastboot_flash.py b/py/test/pytests/fastboot_flash.py
index d87e7e7..85a0a76 100644
--- a/py/test/pytests/fastboot_flash.py
+++ b/py/test/pytests/fastboot_flash.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright 2016 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -14,6 +12,7 @@
 import factory_common  # pylint: disable=unused-import
 from cros.factory.device import device_utils
 from cros.factory.test import factory
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
@@ -21,18 +20,17 @@
 from cros.factory.utils import sync_utils
 
 
-_MSG_SWITCH_TO_FASTBOOT = test_ui.MakeLabel(
-    'Switching device into fastboot.',
-    u'等待待测物进入fastboot')
+_MSG_SWITCH_TO_FASTBOOT = i18n_test_ui.MakeI18nLabel(
+    'Switching device into fastboot.')
 
-_MSG_SWITCH_TO_NORMAL = test_ui.MakeLabel(
-    'Switching device back to normal mode.',
-    u'等待待测物正常开机')
+_MSG_SWITCH_TO_NORMAL = i18n_test_ui.MakeI18nLabel(
+    'Switching device back to normal mode.')
 
 def GetFlashingMessage(partition, file_path):
-  return test_ui.MakeLabel(
-      'Flashing %s to %s.' % (file_path, partition),
-      u'安装 %s 至 %s.' % (file_path, partition))
+  return i18n_test_ui.MakeI18nLabel(
+      'Flashing {file} to {partition}.',
+      file=file_path,
+      partition=partition)
 
 _RE_SENDING_TIME = re.compile(
     r'^sending.*\(([0-9]+) KB\).*\nOKAY\s*\[\s*([0-9]+\.[0-9]+)s\]',
diff --git a/py/test/pytests/finalize/finalize.py b/py/test/pytests/finalize/finalize.py
index 52c2084..3ab4168 100644
--- a/py/test/pytests/finalize/finalize.py
+++ b/py/test/pytests/finalize/finalize.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -30,6 +29,7 @@
 from cros.factory.test import event_log
 from cros.factory.test import factory
 from cros.factory.test import gooftools
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test.rules import phase
 from cros.factory.test import shopfloor
 from cros.factory.test import test_ui
@@ -41,30 +41,21 @@
 from cros.factory.utils import type_utils
 
 
-MSG_CHECKING = test_ui.MakeLabel(
-    'Checking system status for finalization...',
-    '正在检查系统是否已可执行最终程序...')
-MSG_NOT_READY = test_ui.MakeLabel(
+MSG_CHECKING = i18n_test_ui.MakeI18nLabel(
+    'Checking system status for finalization...')
+MSG_NOT_READY = i18n_test_ui.MakeI18nLabel(
     'System is not ready.<br>'
-    'Please fix RED tasks and then press SPACE.',
-    '系统尚未就绪。<br>'
-    '请修正红色项目后按空白键重新检查。')
-MSG_NOT_READY_POLLING = test_ui.MakeLabel(
-    'System is NOT ready. Please fix RED tasks.',
-    '系统尚未就绪。请修正红色项目。')
-MSG_FORCE = test_ui.MakeLabel(
-    'Press “f” to force starting finalization procedure.',
-    '按下 「f」 键以强迫开始最终程序。')
-MSG_READY = test_ui.MakeLabel(
-    'System is READY. Press SPACE to start FINALIZATION.',
-    '系统已準备就绪。 请按空白键开始最终程序!')
-MSG_FINALIZING = test_ui.MakeLabel(
+    'Please fix RED tasks and then press SPACE.')
+MSG_NOT_READY_POLLING = i18n_test_ui.MakeI18nLabel(
+    'System is NOT ready. Please fix RED tasks.')
+MSG_FORCE = i18n_test_ui.MakeI18nLabel(
+    'Press "f" to force starting finalization procedure.')
+MSG_READY = i18n_test_ui.MakeI18nLabel(
+    'System is READY. Press SPACE to start FINALIZATION.')
+MSG_FINALIZING = i18n_test_ui.MakeI18nLabel(
     'Finalizing, please wait.<br>'
     'Do not restart the device or terminate this test,<br>'
-    'or the device may become unusable.',
-    '正在开始最终程序,请稍等.<br>'
-    '不要重启机器或停止测试,<br>'
-    '不然机器将无法开机。')
+    'or the device may become unusable.')
 
 
 class Finalize(unittest.TestCase):
@@ -337,19 +328,16 @@
       return self._CallGoofTool('gooftool verify_switch_dev')
 
     items = [(CheckRequiredTests,
-              test_ui.MakeLabel('Verify all tests passed',
-                                '确认测试项目都已成功了')),
+              i18n_test_ui.MakeI18nLabel('Verify all tests passed')),
              (CheckDevSwitch,
-              test_ui.MakeLabel('Turn off Developer Switch',
-                                '停用开发者开关(DevSwitch)'))]
+              i18n_test_ui.MakeI18nLabel('Turn off Developer Switch'))]
 
     if self.args.write_protection:
       def CheckWriteProtect():
         return self._CallGoofTool('gooftool verify_switch_wp')
 
       items += [(CheckWriteProtect,
-                 test_ui.MakeLabel('Enable write protection pin',
-                                   '确认硬体写入保护已开启'))]
+                 i18n_test_ui.MakeI18nLabel('Enable write protection pin'))]
 
     self.template.SetState(
         '<table style="margin: auto; font-size: 150%"><tr><td>' +
diff --git a/py/test/pytests/finalize_accessory.py b/py/test/pytests/finalize_accessory.py
index d9ebb24..e85933d 100644
--- a/py/test/pytests/finalize_accessory.py
+++ b/py/test/pytests/finalize_accessory.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 # Copyright 2015 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -15,13 +14,14 @@
 from cros.factory.test.env import paths
 from cros.factory.test import event_log
 from cros.factory.test import factory
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 
 
-_MSG_GET_TEST_RESULT = test_ui.MakeLabel('Get the final test result...',
-                                         '检查系统最终测试结果...')
+_MSG_GET_TEST_RESULT = i18n_test_ui.MakeI18nLabel(
+    'Get the final test result...')
 
 
 class FinalizeAccessory(unittest.TestCase):
diff --git a/py/test/pytests/flash_netboot.py b/py/test/pytests/flash_netboot.py
index 8d946aa..1eabc4a 100644
--- a/py/test/pytests/flash_netboot.py
+++ b/py/test/pytests/flash_netboot.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -14,12 +12,13 @@
 import unittest
 
 import factory_common  # pylint: disable=unused-import
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.tools import flash_netboot
 from cros.factory.utils.arg_utils import Arg
 
-_TEST_TITLE = test_ui.MakeLabel('Flash Netboot Firmware', u'烧录 netboot 韧体')
+_TEST_TITLE = i18n_test_ui.MakeI18nLabel('Flash Netboot Firmware')
 _CSS = '#state {text-align:left;}'
 
 
diff --git a/py/test/pytests/flush_testlog.py b/py/test/pytests/flush_testlog.py
index 7896e9c..fbf030b 100644
--- a/py/test/pytests/flush_testlog.py
+++ b/py/test/pytests/flush_testlog.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright 2016 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -9,13 +7,13 @@
 import unittest
 
 import factory_common  # pylint: disable=W0611
-from cros.factory.goofy import updater
 from cros.factory.test import factory
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
+from cros.factory.utils.arg_utils import Arg
 from cros.factory.utils import debug_utils
 from cros.factory.utils import process_utils
-from cros.factory.utils.arg_utils import Arg
 
 _CSS = """
 #state {
@@ -54,9 +52,9 @@
 
       while True:
         try:
-          template.SetState(test_ui.MakeLabel(
-              'Attempting to flush logs upstream...',
-              '同步测试记录...'))
+          template.SetState(
+              i18n_test_ui.MakeI18nLabel(
+                  'Attempting to flush logs upstream...'))
           msg = goofy.FlushTestlog(timeout=self.args.timeout_secs)
           factory.console.info('Logs flushed successfully: %s', msg)
           ui.Pass()
@@ -67,20 +65,16 @@
           # since this may happen repeatedly.
           logging.error('Unable to flush logs: %s', exception_string)
 
-        template.SetState(
-            test_ui.MakeLabel(
-                'Unable to flush logs. Will try again in ',
-                '无法同步测试记录,将于 ') +
-            ('<span id="retry">%d</span>' % retry_secs) +
-            test_ui.MakeLabel(
-                ' seconds.',
-                ' 秒后自动重试。') +
-            '<div class=sync-detail>' +
-            test_ui.Escape(exception_string) + '</div>')
+        msg = lambda secs: i18n_test_ui.MakeI18nLabel(
+            'Unable to flush logs. Will try again in {secs} seconds.',
+            secs=secs)
+        template.SetState('<span id="retry">' + msg(retry_secs) + '</span>' +
+                          '<div class=sync-detail>' +
+                          test_ui.Escape(exception_string) + '</div>')
 
         for i in xrange(retry_secs):
           time.sleep(1)
-          ui.SetHTML(str(retry_secs - i - 1), id='retry')
+          ui.SetHTML(msg(retry_secs - i - 1), id='retry')
 
         retry_secs = min(2 * retry_secs, self.args.retry_secs)
 
diff --git a/py/test/pytests/gyroscope.py b/py/test/pytests/gyroscope.py
index cea5e5d..9c6ac09 100644
--- a/py/test/pytests/gyroscope.py
+++ b/py/test/pytests/gyroscope.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright 2016 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -10,7 +8,6 @@
 
     OperatorTest(
         id='Gyroscope',
-        label_zh=u'陀螺仪',
         pytest_name='gyroscope',
         dargs={
             'rotation_threshold': 1.0,
@@ -25,6 +22,7 @@
 import factory_common  # pylint: disable=unused-import
 from cros.factory.device import device_utils
 from cros.factory.test import factory_task
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
@@ -32,27 +30,26 @@
 from cros.factory.utils import type_utils
 
 
-_MSG_SPACE = test_ui.MakeLabel(
+_MSG_SPACE = i18n_test_ui.MakeI18nLabelWithClass(
     'Please put device on a horizontal plane then press space to '
-    'start calibration.',
-    u'按空白键开始測试。', 'test-info')
-_MSG_IN_PROGRESS = test_ui.MakeLabel(
-    'Please do not move the device.',
-    u'请勿移动待测物。', 'test-info')
-_MSG_START_MOVING = test_ui.MakeLabel(
-    'Please rotate the device.',
-    u'请转动待测物。', 'test-info')
+    'start calibration.', 'test-info')
+_MSG_IN_PROGRESS = i18n_test_ui.MakeI18nLabelWithClass(
+    'Please do not move the device.', 'test-info')
+_MSG_START_MOVING = i18n_test_ui.MakeI18nLabelWithClass(
+    'Please rotate the device.', 'test-info')
 
 def GetPreparingMessage(secs):
-  return test_ui.MakeLabel(
-      'Calibration will be started within %d seconds.'
-      'Please do not move device.' % secs,
-      u'测试程序即将于 %d 秒后开始,请勿移动待测物。' % secs, 'test-info')
+  return i18n_test_ui.MakeI18nLabelWithClass(
+      'Calibration will be started within {secs} seconds.'
+      'Please do not move device.',
+      'test-info',
+      secs=secs)
 
-_MSG_PASS = test_ui.MakeLabel('PASS', u'成功', 'test-pass')
-_MSG_FAIL = test_ui.MakeLabel('FAIL', u'失败', 'test-fail')
 
-_BR = '<br/>'
+_MSG_PASS = i18n_test_ui.MakeI18nLabelWithClass('PASS', 'test-pass')
+_MSG_FAIL = i18n_test_ui.MakeI18nLabelWithClass('FAIL', 'test-fail')
+
+_BR = '<br>'
 
 _CSS = """
   .test-info {font-size: 2em;}
diff --git a/py/test/pytests/hwid.py b/py/test/pytests/hwid.py
index 32e38a0..d2a3e2f 100644
--- a/py/test/pytests/hwid.py
+++ b/py/test/pytests/hwid.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -23,29 +21,23 @@
 from cros.factory.test import factory
 from cros.factory.test import factory_task
 from cros.factory.test import gooftools
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import shopfloor
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 from cros.factory.utils import process_utils
 
-_MESSAGE_FETCH_FROM_SHOP_FLOOR = test_ui.MakeLabel(
-    'Fetching HWID from shop floor server...',
-    u'从 Shop Floor 服务器抓取 HWID 中...',
-    'hwid-font-size')
-_MESSAGE_AUTO_PROBE_HWID = test_ui.MakeLabel('Auto probing HWID...',
-                                             u'自动侦测 HWID 中...',
-                                             'hwid-font-size')
-_MESSAGE_WRITING = (
-    lambda hwid: test_ui.MakeLabel(
-        'Writing HWID: %s' % hwid,
-        u'写入 HWID: %s' % hwid, 'hwid-font-size'))
-_MESSAGE_CHOOSE_HWID = test_ui.MakeLabel('Select HWID:</br></br>',
-                                         u'选择 HWID:</br></br>',
-                                         'hwid-font-size')
-_MESSAGE_HOW_TO_SELECT = test_ui.MakeLabel('</br></br>Select with Enter key',
-                                           u'</br></br>使用 Enter 键选择',
-                                           'hwid-font-size')
+_MESSAGE_FETCH_FROM_SHOP_FLOOR = i18n_test_ui.MakeI18nLabelWithClass(
+    'Fetching HWID from shop floor server...', 'hwid-font-size')
+_MESSAGE_AUTO_PROBE_HWID = i18n_test_ui.MakeI18nLabelWithClass(
+    'Auto probing HWID...', 'hwid-font-size')
+_MESSAGE_WRITING = (lambda hwid: i18n_test_ui.MakeI18nLabelWithClass(
+    'Writing HWID: {hwid}', 'hwid-font-size', hwid=hwid))
+_MESSAGE_CHOOSE_HWID = i18n_test_ui.MakeI18nLabelWithClass(
+    'Select HWID:<br><br>', 'hwid-font-size')
+_MESSAGE_HOW_TO_SELECT = i18n_test_ui.MakeI18nLabelWithClass(
+    '<br><br>Select with Enter key', 'hwid-font-size')
 _MESSAGE_CURRENT_VALUE = lambda hwid: '%s (Current Value)' % hwid
 
 _TEST_DEFAULT_CSS = '.hwid-font-size {font-size: 2em;}'
@@ -60,11 +52,10 @@
     window.test.sendTestEvent("%s", ele.options[idx].value)
 """ % (_SELECT_BOX_ID, _EVENT_SUBTYPE_HWID_SELECT)
 
-_ERR_HWID_NOT_FOUND = test_ui.MakeLabel('Cannot find matched HWID.',
-                                        u'无法找到匹配的 HWID。',
-                                        'hwid-font-size test-error')
+_ERR_HWID_NOT_FOUND = i18n_test_ui.MakeI18nLabelWithClass(
+    'Cannot find matched HWID.', 'hwid-font-size test-error')
 
-_TEST_TITLE = test_ui.MakeLabel('HWID Test', u'HWID测试')
+_TEST_TITLE = i18n_test_ui.MakeI18nLabel('HWID Test')
 
 
 class WriteHWIDTask(factory_task.FactoryTask):
diff --git a/py/test/pytests/hwid_v3.py b/py/test/pytests/hwid_v3.py
index dcf4054..472433d 100644
--- a/py/test/pytests/hwid_v3.py
+++ b/py/test/pytests/hwid_v3.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -16,13 +15,15 @@
 from cros.factory.hwid.v3 import common
 from cros.factory.test.event_log import Log
 from cros.factory.test import factory
+from cros.factory.test.i18n import _
+from cros.factory.test.i18n import test_ui as i18n_test_ui
+from cros.factory.test.rules import phase
 from cros.factory.test import shopfloor
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
-from cros.factory.test.rules import phase
 from cros.factory.test.utils import deploy_utils
-from cros.factory.utils import file_utils
 from cros.factory.utils.arg_utils import Arg
+from cros.factory.utils import file_utils
 
 # If present,  these files will override the board and probe results
 # (for testing).
@@ -74,9 +75,7 @@
     if not self.args.skip_shopfloor:
       shopfloor.update_local_hwid_data(self._dut)
 
-    template.SetState(test_ui.MakeLabel(
-        'Probing components...',
-        '正在探索零件...'))
+    template.SetState(i18n_test_ui.MakeI18nLabel('Probing components...'))
     # check if we are overriding probed results.
     probed_results_file = self._dut.path.join(self.tmpdir,
                                               'probed_results_file')
@@ -105,9 +104,7 @@
       self._dut.SendFile(f, device_info_file)
 
     if self.args.generate:
-      template.SetState(test_ui.MakeLabel(
-          'Generating HWID (v3)...',
-          '正在产生 HWID (v3)...'))
+      template.SetState(i18n_test_ui.MakeI18nLabel('Generating HWID (v3)...'))
       generate_cmd = ['hwid', 'generate',
                       '--probed-results-file', probed_results_file,
                       '--device-info-file', device_info_file,
@@ -139,9 +136,10 @@
     else:
       encoded_string = self.factory_tools.CheckOutput(['hwid', 'read']).strip()
 
-    template.SetState(test_ui.MakeLabel(
-        'Verifying HWID (v3): %s...' % (encoded_string or '(unchanged)'),
-        u'正在验证 HWID (v3): %s...' % (encoded_string or u'(不变)')))
+    template.SetState(
+        i18n_test_ui.MakeI18nLabel(
+            'Verifying HWID (v3): {encoded_string}...',
+            encoded_string=(encoded_string or _('(unchanged)'))))
 
     verify_cmd = ['hwid', 'verify',
                   '--probed-results-file', probed_results_file,
@@ -159,7 +157,8 @@
     Log('hwid_verified', hwid=encoded_string)
 
     if self.args.generate:
-      template.SetState(test_ui.MakeLabel(
-          'Setting HWID (v3): %s...' % encoded_string,
-          u'正在写入 HWID (v3): %s...' % encoded_string))
+      template.SetState(
+          i18n_test_ui.MakeI18nLabel(
+              'Setting HWID (v3): {encoded_string}...',
+              encoded_string=encoded_string))
       self.factory_tools.CheckCall(['hwid', 'write', encoded_string])
diff --git a/py/test/pytests/keyboard_backlight.py b/py/test/pytests/keyboard_backlight.py
index b5964d6..f20d3b4 100644
--- a/py/test/pytests/keyboard_backlight.py
+++ b/py/test/pytests/keyboard_backlight.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -10,18 +8,18 @@
 import unittest
 
 import factory_common  # pylint: disable=unused-import
+from cros.factory.test.i18n import _
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils import process_utils
 
 
-_TEST_TITLE = test_ui.MakeLabel('Keyboard Backlight Test', u'鍵盤背光測試')
+_TEST_TITLE = i18n_test_ui.MakeI18nLabel('Keyboard Backlight Test')
 
-_SUBTESTS = (('lights up', u'亮起', '100'),
-             ('is off', u'熄滅', '0'))
-
-_INSTRUCTION_EN = 'If the keyboard backlight %s, press ENTER. '
-_INSTRUCTION_ZH = u'檢查鍵盤背光是否%s,是請按ENTER。'
+_SUBTESTS = (
+    (_('If the keyboard backlight lights up, press ENTER. '), '100'),
+    (_('If the keyboard backlight is off, press ENTER. '), '0'))
 
 
 class KeyboardBacklightTest(unittest.TestCase):
@@ -32,13 +30,12 @@
     self._current = 0
 
   def NextSubTest(self):
-    inst_en = _INSTRUCTION_EN % _SUBTESTS[self._current][0]
-    inst_zh = _INSTRUCTION_ZH % _SUBTESTS[self._current][1]
-    instruction = (test_ui.MakeLabel(inst_en, inst_zh) +
+    inst = _SUBTESTS[self._current][0]
+    instruction = (i18n_test_ui.MakeI18nLabel(inst) +
                    test_ui.MakePassFailKeyLabel(pass_key=False))
     self._template.SetState(instruction)
     process_utils.Spawn(['ectool', 'pwmsetkblight',
-                         _SUBTESTS[self._current][2]], ignore_stdout=True,
+                         _SUBTESTS[self._current][1]], ignore_stdout=True,
                         log_stderr_on_error=True, check_call=True)
     self._current = self._current + 1
 
diff --git a/py/test/pytests/keyboard_smt.py b/py/test/pytests/keyboard_smt.py
index 91f028e..2ed5407 100644
--- a/py/test/pytests/keyboard_smt.py
+++ b/py/test/pytests/keyboard_smt.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -19,6 +17,7 @@
 from cros.factory.test import countdown_timer
 from cros.factory.test import factory
 from cros.factory.test.fixture import bft_fixture
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.test.utils import evdev_utils
@@ -31,8 +30,8 @@
 _ID_MATCHED_SEQUENCE = 'matched-sequence'
 _ID_COUNTDOWN_TIMER = 'keyboard-test-timer'
 
-_MSG_EXPECTED_SEQUENCE = test_ui.MakeLabel(
-    'Expected keycode sequence:', u'目標鍵序:', 'test-info')
+_MSG_EXPECTED_SEQUENCE = i18n_test_ui.MakeI18nLabelWithClass(
+    'Expected keycode sequence:', 'test-info')
 
 _HTML_KEYBOARD = '<br>\n'.join([
     '<div>%s <span id="%s"></span><span id="%s"></span></div>' % (
diff --git a/py/test/pytests/led/led.py b/py/test/pytests/led/led.py
index 53a999c..3feda32 100644
--- a/py/test/pytests/led/led.py
+++ b/py/test/pytests/led/led.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -7,7 +5,6 @@
 """Uses ectool to control the onboard LED light, and lets either operator
 or SMT fixture confirm LED functionality."""
 
-from collections import namedtuple
 import logging
 import random
 import time
@@ -17,6 +14,8 @@
 from cros.factory.device import device_utils
 from cros.factory.device import led as led_module
 from cros.factory.test import factory_task
+from cros.factory.test.i18n import _
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 # The right BFTFixture module is dynamically imported based on args.bft_fixture.
 # See setUp() for more detail.
 from cros.factory.test.fixture import bft_fixture
@@ -25,28 +24,27 @@
 from cros.factory.utils.arg_utils import Arg
 
 
-_TEST_TITLE = test_ui.MakeLabel('LED Test', u'LED 测试')
+_TEST_TITLE = i18n_test_ui.MakeI18nLabel('LED Test')
 
 # True to test all colors regardless of failure.
 _FAIL_LATER = True
 _SHOW_RESULT_SECONDS = 0.5
 
-I18nLabel = namedtuple('I18nLabel', 'en zh')
 LEDColor = led_module.LED.Color
 LEDIndex = led_module.LED.Index
 _COLOR_LABEL = {
-    LEDColor.YELLOW: I18nLabel('yellow', u'黃色'),
-    LEDColor.GREEN: I18nLabel('green', u'绿色'),
-    LEDColor.RED: I18nLabel('red', u'紅色'),
-    LEDColor.WHITE: I18nLabel('white', u'白色'),
-    LEDColor.BLUE: I18nLabel('blue', u'蓝色'),
-    LEDColor.AMBER: I18nLabel('amber', u'琥珀色'),
-    LEDColor.OFF: I18nLabel('off', u'关闭')}
+    LEDColor.YELLOW: _('yellow'),
+    LEDColor.GREEN: _('green'),
+    LEDColor.RED: _('red'),
+    LEDColor.WHITE: _('white'),
+    LEDColor.BLUE: _('blue'),
+    LEDColor.AMBER: _('amber'),
+    LEDColor.OFF: _('off')}
 _INDEX_LABEL = {
-    None: I18nLabel('', ''),
-    LEDIndex.POWER: I18nLabel('power', u'电源'),
-    LEDIndex.BATTERY: I18nLabel('battery', u'电池'),
-    LEDIndex.ADAPTER: I18nLabel('adapter', u'电源适配器')}
+    None: _('LED'),
+    LEDIndex.POWER: _('power LED'),
+    LEDIndex.BATTERY: _('battery LED'),
+    LEDIndex.ADAPTER: _('adapter LED')}
 
 # Hash values are: (LED color, readable text color).
 _COLOR_CODE = {
@@ -78,7 +76,7 @@
 
 _HTML_RESULT = (
     '<div class="result-line">' +
-    test_ui.MakeLabel('Result: ', u'测试结果:') +
+    i18n_test_ui.MakeI18nLabel('Result: ') +
     '<span id="result"></span></div>')
 
 _CSS = """
@@ -133,9 +131,9 @@
     led: dut.led.LED instance to control LED.
     nth: The number of task.
     color: LEDColor to inspect.
-    color_label: I18nLabel for inspected color.
+    color_label: Label for inspected color.
     index: Target LED to inspect. None means default LED.
-    index_label: I18nLabel for inspected index.
+    index_label: Label for inspected index.
   """
 
   def __init__(self, ui, template, led, nth, color, color_label,
@@ -179,17 +177,14 @@
 
   def _InitUI(self):
     if self._color == LEDColor.OFF:
-      instruction = test_ui.MakeLabel(
-          'If the <strong>%s LED</strong> is <strong>off</strong>, '
-          'press ENTER.' % self._index_label.en,
-          u'請檢查 <strong>%s LED</strong> 是否 <strong>关掉</strong> 了,'
-          u'关掉了請按 ENTER。' % self._index_label.zh)
+      instruction = i18n_test_ui.MakeI18nLabel(
+          'If the <strong>{name}</strong> is <strong>off</strong>, '
+          'press ENTER.', name=self._index_label)
     else:
-      instruction = test_ui.MakeLabel(
-          'If the <strong>%s LED</strong> lights up in <strong>%s</strong>, '
-          'press ENTER.' % (self._index_label.en, self._color_label.en),
-          u'請檢查 <strong>%s LED</strong> 是否亮 <strong>%s</strong>,'
-          u'是請按 ENTER。' % (self._index_label.zh, self._color_label.zh))
+      instruction = i18n_test_ui.MakeI18nLabel(
+          'If the <strong>{name}</strong> lights up in '
+          '<strong>{color}</strong>, press ENTER.',
+          name=self._index_label, color=self._color_label)
     self._ui.AppendCSS(_CSS)
     self._template.SetState(instruction)
 
@@ -210,19 +205,17 @@
     self._color_options = color_options
 
   def _InitUI(self):
-    desc = test_ui.MakeLabel(
-        '<span class="sub-title">Test %d</span><br />'
-        'Please press number key according to the <strong>%s LED</strong> color'
-        % (self._nth, self._index_label.en),
-        u'<span class="sub-title">测试 %d</span><br />'
-        u'请根据 <strong>%s LED</strong> 的颜色按下数字键'
-        % (self._nth, self._index_label.zh))
+    desc = i18n_test_ui.MakeI18nLabel(
+        '<span class="sub-title">Test {test_id}</span><br>'
+        'Please press number key according to the <strong>{name}</strong> '
+        'color',
+        test_id=self._nth, name=self._index_label)
 
     btn_ui = ''.join([
         _HTML_KEY_TEMPLATE % (_COLOR_CODE[c] + (_SELECT_COLOR_EVENT, j, j + 1))
         for j, c in enumerate(self._color_options)])
 
-    ui = [desc, '<br /><br />', btn_ui, _HTML_RESULT]
+    ui = [desc, '<br><br>', btn_ui, _HTML_RESULT]
 
     def _Judge(event):
       if event.data == target:
@@ -253,9 +246,9 @@
     fixture: BFTFixture instance.
     led: dut.led.LED instance to control LED.
     color: LEDColor to inspect.
-    color_label: I18nLabel for inspected color.
+    color_label: Label for inspected color.
     index: Target LED to inspect (unused yet).
-    index_label: I18nLabel for inspected index (unused yet).
+    index_label: Label for inspected index (unused yet).
   """
 
   def __init__(self, fixture, led, color, color_label, index, index_label):
@@ -282,7 +275,7 @@
         self.Pass()
       else:
         # Fail later to detect all colors.
-        self.Fail('Unable to detect %s LED.' % self._color_label.en,
+        self.Fail('Unable to detect %s LED.' % self._color_label['en-US'],
                   later=_FAIL_LATER)
     except bft_fixture.BFTFixtureException:
       logging.exception('Failed to send command to BFT fixture')
@@ -309,11 +302,7 @@
                    LEDColor.OFF]),
       Arg('target_leds', (list, tuple),
           'List of LEDs to test. If specified, it turns off all LEDs first, '
-          'and sets them to auto after test.', optional=True),
-      Arg('index_i18n', dict,
-          'Mapping of (index, zh) translations.  If an index is used without '
-          'providing a translation, it will simply show the original index '
-          'name.', optional=True, default={})]
+          'and sets them to auto after test.', optional=True)]
 
   def setUp(self):
     self._dut = device_utils.CreateDUTInterface()
@@ -376,12 +365,10 @@
     self._task_manager.Run()
 
   def _GetIndexLabel(self, index):
-    if index in self.args.index_i18n:
-      return I18nLabel(index, self.args.index_i18n[index])
-    elif index in _INDEX_LABEL:
+    if index in _INDEX_LABEL:
       return _INDEX_LABEL[index]
     else:
-      return I18nLabel(index, index)
+      return _(index)
 
   def _SetAllLED(self, leds, color):
     """Sets all LEDs to a given color.
diff --git a/py/test/pytests/lid_switch/lid_switch.py b/py/test/pytests/lid_switch/lid_switch.py
index 8676734..ca6d953 100644
--- a/py/test/pytests/lid_switch/lid_switch.py
+++ b/py/test/pytests/lid_switch/lid_switch.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -17,6 +15,7 @@
 # The right BFTFixture module is dynamically imported based on args.bft_fixture.
 # See LidSwitchTest.setUp() for more detail.
 from cros.factory.test.fixture import bft_fixture
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.test.utils import audio_utils
@@ -27,15 +26,15 @@
 _DEFAULT_TIMEOUT = 30
 _SERIAL_TIMEOUT = 1
 
-_MSG_PROMPT_CLOSE = test_ui.MakeLabel(
-    'Close then open the lid', u'关上接着打开上盖', 'lid-test-info')
-_MSG_PROMPT_OPEN = test_ui.MakeLabel(
-    'Open the lid', u'请打开上盖', 'lid-test-info')
+_MSG_PROMPT_CLOSE = i18n_test_ui.MakeI18nLabelWithClass(
+    'Close then open the lid', 'lid-test-info')
+_MSG_PROMPT_OPEN = i18n_test_ui.MakeI18nLabelWithClass('Open the lid',
+                                                       'lid-test-info')
 
-_MSG_LID_FIXTURE_CLOSE = test_ui.MakeLabel(
-    'Magnetizing lid sensor', u'磁化上盖感应器', 'lid-test-info')
-_MSG_LID_FIXTURE_OPEN = test_ui.MakeLabel(
-    'Demagnetizing lid sensor', u'消磁化上盖感应器', 'lid-test-info')
+_MSG_LID_FIXTURE_CLOSE = i18n_test_ui.MakeI18nLabelWithClass(
+    'Magnetizing lid sensor', 'lid-test-info')
+_MSG_LID_FIXTURE_OPEN = i18n_test_ui.MakeI18nLabelWithClass(
+    'Demagnetizing lid sensor', 'lid-test-info')
 
 _ID_PROMPT = 'lid-test-prompt'
 _ID_COUNTDOWN_TIMER = 'lid-test-timer'
diff --git a/py/test/pytests/lightbar.py b/py/test/pytests/lightbar.py
index 951a43f..e668fee 100644
--- a/py/test/pytests/lightbar.py
+++ b/py/test/pytests/lightbar.py
@@ -12,16 +12,18 @@
 
 import factory_common  # pylint: disable=unused-import
 from cros.factory.test import factory
+from cros.factory.test import i18n
+from cros.factory.test.i18n import _
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 from cros.factory.utils import process_utils
 
 
-_TEST_TITLE = test_ui.MakeLabel('Lightbar Test', u'光棒测试')
-_TEST_PROMPT = lambda color_en, color_zh: test_ui.MakeLabel(
-    'Is the lightbar %s?<br>Press SPACE if yes, "f" if no.' % color_en,
-    u'光棒是否为%s?<br>是请按空白键,不是请按 f 。' % color_zh)
+_TEST_TITLE = i18n_test_ui.MakeI18nLabel('Lightbar Test')
+_TEST_PROMPT = lambda color: i18n_test_ui.MakeI18nLabel(
+    'Is the lightbar {color}?<br>Press SPACE if yes, "f" if no.', color=color)
 _CSS = 'body { font-size: 2em; }'
 
 
@@ -31,13 +33,13 @@
   ARGS = [
       Arg('colors_to_test', type=(tuple, list),
           help=('a list of colors to test; each element of the list is a tuple '
-                'of ((label_en, label_zh), [LED, RED, GREEN, BLUE])'),
+                'of (label, [LED, RED, GREEN, BLUE])'),
           default=[
-              (('red', u'红色'), [4, 255, 0, 0]),
-              (('green', u'绿色'), [4, 0, 255, 0]),
-              (('blue', u'蓝色'), [4, 0, 0, 255]),
-              (('dark', u'全暗'), [4, 0, 0, 0]),
-              (('white', u'白色'), [4, 255, 255, 255]),
+              (_('red'), [4, 255, 0, 0]),
+              (_('green'), [4, 0, 255, 0]),
+              (_('blue'), [4, 0, 0, 255]),
+              (_('dark'), [4, 0, 0, 0]),
+              (_('white'), [4, 255, 255, 255]),
           ]),
   ]
 
@@ -51,6 +53,10 @@
     self.ECToolLightbar(['on'])
     self.ECToolLightbar(['init'])
     self.ECToolLightbar(['seq', 'stop'])
+    self.args.colors_to_test = [
+        (i18n.Translated(label), color)
+        for label, color in self.args.colors_to_test
+    ]
 
   def tearDown(self):
     self.ECToolLightbar(['seq', 'run'])
@@ -81,8 +87,8 @@
       color_index: The index of self.args.colors_to_test to test.
     """
     labels, lrgb = self.args.colors_to_test[color_index]
-    logging.info('Testing %s (%s)...', labels[0], lrgb)
-    self._template.SetState(_TEST_PROMPT(*labels))
+    logging.info('Testing %s (%s)...', labels['en-US'], lrgb)
+    self._template.SetState(_TEST_PROMPT(labels))
     self.ECToolLightbar(lrgb)
 
   def TestNextColorOrPass(self, _):
@@ -96,7 +102,7 @@
   def FailTest(self, _):
     """Callback function for keypress event of f key."""
     labels, _ = self.args.colors_to_test[self._test_color_index]
-    self._ui.Fail('Lightbar failed to light up in %s' % labels[0])
+    self._ui.Fail('Lightbar failed to light up in %s' % labels['en-US'])
 
   def runTest(self):
     self.TestColor(self._test_color_index)
diff --git a/py/test/pytests/line_check_item.py b/py/test/pytests/line_check_item.py
index b9120bf..64fb34a 100644
--- a/py/test/pytests/line_check_item.py
+++ b/py/test/pytests/line_check_item.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -7,21 +5,23 @@
 """A factory test to check a list of commands.
 """
 
+from collections import namedtuple
 import subprocess
 import unittest
-from collections import namedtuple
 
 import factory_common  # pylint: disable=unused-import
 from cros.factory.device import device_utils
 from cros.factory.test import event_log
 from cros.factory.test import factory
+from cros.factory.test import i18n
+from cros.factory.test.i18n import arg_utils as i18n_arg_utils
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 from cros.factory.utils import process_utils
 
-CheckItem = namedtuple('CheckItem', 'instruction_en instruction_zh'
-                       ' command judge_to_pass')
+CheckItem = namedtuple('CheckItem', 'instruction command judge_to_pass')
 
 
 class LineCheckItemTest(unittest.TestCase):
@@ -32,17 +32,18 @@
     _items: A list of CheckItems.
     _current: current test item index in _items.
   """
-  ARGS = [
-      Arg('title_en', (str, unicode), 'English test title.', optional=False),
-      Arg('title_zh', (str, unicode), 'Chinese test title.', optional=False),
+  ARGS = i18n_arg_utils.BackwardCompatibleI18nArgs('title', 'test title.') + [
       Arg('items', list,
           ('A list of item to check. Each item can be either a simple string\n'
-           'as shell command to execute, or a tuple in the format:\n'
+           'as shell command to execute, or a tuple in one of the formats:\n'
+           '\n'
+           '  (instruction, command, judge_to_pass)\n'
            '\n'
            '  (instruction_en, instruction_zh, command, judge_to_pass)\n'
            '\n'
            'The fields are:\n'
            '\n'
+           '- instruction: instruction, would be passed to i18n.Translated.\n'
            '- instruction_en: (str or unicode) instruction in English.\n'
            '- instruction_zh: (str or unicode) instruction in Chinese.\n'
            '- command: (list or str) commands to be passed to Spawn.\n'
@@ -59,17 +60,40 @@
 
   def setUp(self):
     """Initializes _ui, _template, _current, and _items"""
+    i18n_arg_utils.ParseArg(self, 'title')
     self._ui = (test_ui.UI() if self.args.has_ui
                 else test_ui.DummyUI(self))
     self._template = (ui_templates.OneSection(self._ui) if self.args.has_ui
                       else ui_templates.DummyTemplate())
+
+    def _CommandToLabel(command, length=50):
+      return (command[:length] + ' ...') if len(command) > length else command
+
     self._items = []
+    for item in self.args.items:
+      if isinstance(item, basestring):
+        check_item = CheckItem(
+            i18n.NoTranslation(_CommandToLabel(item)), item, False)
+      elif isinstance(item, tuple) and len(item) == 4:
+        # TODO(pihsun): This is to maintain backward compatibility. Should be
+        #               removed after test lists are migrated to new format.
+        check_item = CheckItem(
+            i18n.Translated({'en-US': item[0], 'zh-CN': item[1]},
+                            translate=False),
+            item[2], item[3])
+      elif isinstance(item, tuple) and len(item) == 3:
+        check_item = CheckItem(
+            i18n.Translated(item[0], translate=False), item[1], item[2])
+      else:
+        raise ValueError('Unknown item %r in args.items.' % item)
+      self._items.append(check_item)
+
     self._current = 0
     self._dut = (None if self.args.run_locally else
                  device_utils.CreateDUTInterface())
 
   def NeedToJudgeSubTest(self):
-    """Returns whether current subtest needs user to judege pass/fail or not."""
+    """Returns whether current subtest needs user to judge pass/fail or not."""
     return self._items[self._current].judge_to_pass
 
   def RunSubTest(self):
@@ -79,10 +103,9 @@
     Enter/Esc. If current subtest does not need to be judges, proceed to
     the next subtest.
     """
-    inst_en = self._items[self._current].instruction_en
-    inst_zh = self._items[self._current].instruction_zh
+    inst = self._items[self._current].instruction
     command = self._items[self._current].command
-    instruction = test_ui.MakeLabel(inst_en, inst_zh)
+    instruction = i18n_test_ui.MakeI18nLabel(inst)
     if self.NeedToJudgeSubTest():
       instruction = instruction + '<br>' + test_ui.MakePassFailKeyLabel()
     self._template.SetState(instruction)
@@ -148,17 +171,7 @@
 
   def runTest(self):
     """Main entrance of the test."""
-
-    def _CommandToLabel(command, length=50):
-        return (command[:length] + ' ...') if len(command) > length else command
-
-    # pylint: disable=protected-access
-    self._items = [CheckItem._make(
-        (_CommandToLabel(item), _CommandToLabel(item), item, False)
-        if isinstance(item, basestring) else item)
-        for item in self.args.items]
-    self._template.SetTitle(test_ui.MakeLabel(self.args.title_en,
-                                              self.args.title_zh))
+    self._template.SetTitle(i18n_test_ui.MakeI18nLabel(self.args.title))
     self._ui.BindKeyJS(test_ui.ENTER_KEY,
                        'test.sendTestEvent("enter_key_pressed", {});')
     self._ui.BindKeyJS(test_ui.ESCAPE_KEY,
diff --git a/py/test/pytests/memory_size.py b/py/test/pytests/memory_size.py
index 177c40b..63ac7c5 100644
--- a/py/test/pytests/memory_size.py
+++ b/py/test/pytests/memory_size.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright 2015 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -17,6 +15,7 @@
 import unittest
 
 import factory_common  # pylint: disable=unused-import
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import shopfloor
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
@@ -53,8 +52,7 @@
     ui.Run(blocking=False, on_finish=Done)
     ui.AppendCSS('.large { font-size: 200% }')
 
-    template.SetState(test_ui.MakeLabel('Checking memory info...',
-                                        u'正在检查内存大小...'))
+    template.SetState(i18n_test_ui.MakeI18nLabel('Checking memory info...'))
 
     # Get memory info using mosys.
     ret = process_utils.CheckOutput(
@@ -90,16 +88,15 @@
 
       def HandleError(trace):
         template.SetState(
-            test_ui.MakeLabel('Shop floor exception:',
-                              'Shop floor 错误:',
-                              'test-status-failed large') +
+            i18n_test_ui.MakeI18nLabelWithClass(
+                'Shop floor exception:',
+                'test-status-failed large') +
             '<p>' +
             test_ui.Escape(trace) +
             '<p><br>' +
             """<button onclick="test.sendTestEvent('retry')">""" +
-            test_ui.MakeLabel('Retry', '重试') +
-            '</button>'
-            )
+            i18n_test_ui.MakeI18nLabel('Retry') +
+            '</button>')
         process_utils.WaitEvent(self._event)
         self._event.clear()
 
diff --git a/py/test/pytests/network_setup/network_setup.py b/py/test/pytests/network_setup/network_setup.py
index b5ccefd..aa891e0 100644
--- a/py/test/pytests/network_setup/network_setup.py
+++ b/py/test/pytests/network_setup/network_setup.py
@@ -1,5 +1,4 @@
 #!/usr/bin/env python
-# -*- coding: UTF-8 -*-
 # Copyright 2017 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -37,6 +36,7 @@
 import unittest
 
 import factory_common  # pylint: disable=unused-import
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import state
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
@@ -47,7 +47,7 @@
 from cros.factory.utils import sync_utils
 
 
-_TITLE = test_ui.MakeLabel('Setup network connection', u'设定网络连线')
+_TITLE = i18n_test_ui.MakeI18nLabel('Setup network connection')
 
 _ID_SUBTITLE_DIV = 'subtitle'
 _ID_MESSAGE_DIV = 'message'
@@ -61,12 +61,11 @@
 
 def _GetSubtitleForInterface(interface):
   interface = '<b>%s</b>' % interface
-  return test_ui.MakeLabel(
-      'Setting up interface %s' % interface,
-      u'正在设定网络介面 %s' % interface)
+  return i18n_test_ui.MakeI18nLabel(
+      'Setting up interface {interface}', interface=interface)
 
-_PRESS_SPACE = test_ui.MakeLabel(
-    'Press space to continue', u'请按空白键继续')
+
+_PRESS_SPACE = i18n_test_ui.MakeI18nLabel('Press space to continue')
 
 
 ErrorCode = connection_manager.ConnectionManagerException.ErrorCode
@@ -74,17 +73,14 @@
 def _ErrorCodeToMessage(error_code, interface):
   interface = '<b>%s</b>' % interface
   if error_code == ErrorCode.NO_PHYSICAL_LINK:
-    return test_ui.MakeLabel(
-        'No physical link on %s' % interface,
-        u'%s 没有连接网络线' % interface),
+    return i18n_test_ui.MakeI18nLabel(
+        'No physical link on {interface}', interface=interface),
   if error_code == ErrorCode.INTERFACE_NOT_FOUND:
-    return test_ui.MakeLabel(
-        'Interface %s not found' % interface,
-        u'找不到网络介面 %s' % interface),
+    return i18n_test_ui.MakeI18nLabel(
+        'Interface {interface} not found', interface=interface),
   if error_code == ErrorCode.NO_SELECTED_SERVICE:
-    return test_ui.MakeLabel(
-        'Interface %s not initialized' % interface,
-        u'网络介面 %s 未成功初始化' % interface),
+    return i18n_test_ui.MakeI18nLabel(
+        'Interface {interface} not initialized', interface=interface),
 
 
 class NetworkConnectionSetup(unittest.TestCase):
diff --git a/py/test/pytests/ping_test.py b/py/test/pytests/ping_test.py
index d2aaab3..565aa68 100644
--- a/py/test/pytests/ping_test.py
+++ b/py/test/pytests/ping_test.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright 2015 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -18,7 +16,6 @@
     # Checks the successful pings are >= 60% at the end of the test.
     OperatorTest(
         id='ping_test',
-        label_zh=u'连线测试',
         pytest_name='ping_test',
         dargs={'host': '192.168.0.1',
                'interval_secs': 10,
@@ -31,7 +28,6 @@
     # are >= 60% overall.
     OperatorTest(
         id='ping_test',
-        label_zh=u'连线测试',
         pytest_name='ping_test',
         dargs={'host': '192.168.0.1',
                'interval_secs': 10,
@@ -47,13 +43,14 @@
 import unittest
 
 import factory_common  # pylint: disable=unused-import
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 from cros.factory.utils import process_utils
 from cros.factory.utils import time_utils
 
-_TEST_TITLE = test_ui.MakeLabel('Ping test', u'连线测试')
+_TEST_TITLE = i18n_test_ui.MakeI18nLabel('Ping test')
 _CSS = '#state {text-align:left;}'
 
 
diff --git a/py/test/pytests/pointing_device.py b/py/test/pytests/pointing_device.py
index 0f02a89..8ac64c7 100644
--- a/py/test/pytests/pointing_device.py
+++ b/py/test/pytests/pointing_device.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -15,29 +13,26 @@
 import unittest
 
 import factory_common  # pylint: disable=unused-import
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 from cros.factory.utils import process_utils
 
 
-_MSG_TEST_TITLE = test_ui.MakeLabel('Non-touchpad Pointing Device Test',
-                                    u'非触控板之指向装置测试')
-_MSG_INSTRUCTION = test_ui.MakeLabel(
-    'Please move the pointer over four quarters.', u'请移動鼠標至此文字四周')
-_MSG_MOVE_HERE = test_ui.MakeLabel('Move Here!', u'移動鼠標至此')
-_MSG_INSTRUCTION_CLICK = test_ui.MakeLabel(
-    'Please click the pointing device.',
-    u'请按下指向装置左键')
-_MSG_INSTRUCTION_RIGHT_CLICK = test_ui.MakeLabel(
-    'Please right-click the pointing device.',
-    u'请按下指向装置右键')
-_MSG_INSTRUCTION_SCROLL_UP = test_ui.MakeLabel(
-    'Please scroll up with the pointing device.',
-    u'请用指向装置向上卷动')
-_MSG_INSTRUCTION_SCROLL_DOWN = test_ui.MakeLabel(
-    'Please scroll down with the pointing device.',
-    u'请用指向装置向下卷动')
+_MSG_TEST_TITLE = i18n_test_ui.MakeI18nLabel(
+    'Non-touchpad Pointing Device Test')
+_MSG_INSTRUCTION = i18n_test_ui.MakeI18nLabel(
+    'Please move the pointer over four quarters.')
+_MSG_MOVE_HERE = i18n_test_ui.MakeI18nLabel('Move Here!')
+_MSG_INSTRUCTION_CLICK = i18n_test_ui.MakeI18nLabel(
+    'Please click the pointing device.')
+_MSG_INSTRUCTION_RIGHT_CLICK = i18n_test_ui.MakeI18nLabel(
+    'Please right-click the pointing device.')
+_MSG_INSTRUCTION_SCROLL_UP = i18n_test_ui.MakeI18nLabel(
+    'Please scroll up with the pointing device.')
+_MSG_INSTRUCTION_SCROLL_DOWN = i18n_test_ui.MakeI18nLabel(
+    'Please scroll down with the pointing device.')
 
 _CSS = """
 .pd-quarter { height: 50%; width: 50%; position: absolute; display: table;}
diff --git a/py/test/pytests/power_under_stress.py b/py/test/pytests/power_under_stress.py
index a94f6fd..ab54260 100644
--- a/py/test/pytests/power_under_stress.py
+++ b/py/test/pytests/power_under_stress.py
@@ -1,5 +1,4 @@
 #!/usr/bin/env python
-# -*- coding: UTF-8 -*-
 # Copyright 2016 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -11,6 +10,7 @@
 import factory_common  # pylint: disable=unused-import
 from cros.factory.device import device_utils
 from cros.factory.test.fixture import bft_fixture
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.test.utils import stress_manager
@@ -25,17 +25,14 @@
 </div>
 """
 
-_VOLTAGE_FMT_STR = lambda v: test_ui.MakeLabel(
-    'Voltage: %d mV' % v,
-    u'电压: %d mV' % v)
+_VOLTAGE_FMT_STR = lambda voltage: i18n_test_ui.MakeI18nLabel(
+    'Voltage: {voltage} mV', voltage=voltage)
 
-_CURRENT_FMT_STR = lambda i: test_ui.MakeLabel(
-    'Current: %d mA' % i,
-    u'电流: %d mA' % i)
+_CURRENT_FMT_STR = lambda current: i18n_test_ui.MakeI18nLabel(
+    'Current: {current} mA', current=current)
 
-_COUNTDOWN_FMT_STR = lambda t: test_ui.MakeLabel(
-    'Count Down: %d s' % t,
-    u'倒数 %d 秒' % t)
+_COUNTDOWN_FMT_STR = lambda secs: i18n_test_ui.MakeI18nLabel(
+    'Count Down: {secs} s', secs=secs)
 
 
 class PowerUnderStressTest(unittest.TestCase):
diff --git a/py/test/pytests/probe/probe.py b/py/test/pytests/probe/probe.py
index 5ed03ad..7b7f63b 100644
--- a/py/test/pytests/probe/probe.py
+++ b/py/test/pytests/probe/probe.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 # Copyright 2016 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -45,9 +44,10 @@
 from cros.factory.device import device_utils
 from cros.factory.test.args import Arg
 from cros.factory.test import factory
-from cros.factory.test.utils import deploy_utils
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
+from cros.factory.test.utils import deploy_utils
 
 
 # The config files should be placed in the py/test/pytests/probe/ folder.
@@ -150,7 +150,8 @@
 
     html = [
         table_html.GenerateHTML(), '<br>',
-        test_ui.MakeLabel('Press SPACE to continue', u'按空白键继续', 'prompt')]
+        i18n_test_ui.MakeI18nLabelWithClass('Press SPACE to continue', 'prompt')
+    ]
     self._template.SetState(''.join(html))
     self._ui.BindKeyJS(
         test_ui.SPACE_KEY,
diff --git a/py/test/pytests/probe_sim.py b/py/test/pytests/probe_sim.py
index ec608b8..437bf92 100644
--- a/py/test/pytests/probe_sim.py
+++ b/py/test/pytests/probe_sim.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -27,6 +25,7 @@
 from cros.factory.test import event
 from cros.factory.test import event_log
 from cros.factory.test import factory_task
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
@@ -35,13 +34,13 @@
 _SIM_PRESENT_RE = r'IMSI: (\d{14,15})'
 _SIM_NOT_PRESENT_RE = r'SIM: /$'
 
-_TEST_TITLE = test_ui.MakeLabel('SIM Card Test', u'SIM卡测试')
-_INSERT_SIM_INSTRUCTION = test_ui.MakeLabel(
-    'Please insert the SIM card', u'請插入SIM卡')
-_REMOVE_SIM_INSTRUCTION = test_ui.MakeLabel(
-    'Detected! Please remove the SIM card', u'已經偵测SIM卡, 請移除SIM卡')
-_CHECK_SIM_INSTRUCTION = test_ui.MakeLabel(
-    'Checking SIM card is present or not...', u'检查SIM卡是否存在')
+_TEST_TITLE = i18n_test_ui.MakeI18nLabel('SIM Card Test')
+_INSERT_SIM_INSTRUCTION = i18n_test_ui.MakeI18nLabel(
+    'Please insert the SIM card')
+_REMOVE_SIM_INSTRUCTION = i18n_test_ui.MakeI18nLabel(
+    'Detected! Please remove the SIM card')
+_CHECK_SIM_INSTRUCTION = i18n_test_ui.MakeI18nLabel(
+    'Checking SIM card is present or not...')
 
 _INSERT_CHECK_PERIOD_SECS = 1
 _INSERT_CHECK_MAX_WAIT = 60
diff --git a/py/test/pytests/probe_sim_card_tray.py b/py/test/pytests/probe_sim_card_tray.py
index 0eefdbc..ecfedf7 100644
--- a/py/test/pytests/probe_sim_card_tray.py
+++ b/py/test/pytests/probe_sim_card_tray.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -25,20 +23,18 @@
 from cros.factory.test import event
 from cros.factory.test import factory
 from cros.factory.test import factory_task
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 from cros.factory.utils import file_utils
 
 
-_TEST_TITLE = test_ui.MakeLabel('SIM Card Tray Test', u'SIM卡卡盘测试')
-_INSERT_TRAY_INSTRUCTION = test_ui.MakeLabel(
-    'Please insert the SIM card tray', u'請插入SIM卡卡盘',
-    'instruction-font-size')
-_REMOVE_TRAY_INSTRUCTION = test_ui.MakeLabel(
-    'Detected! Please remove the SIM card tray',
-    u'已經偵测SIM卡卡盘, 請移除SIM卡卡盘',
-    'instruction-font-size')
+_TEST_TITLE = i18n_test_ui.MakeI18nLabel('SIM Card Tray Test')
+_INSERT_TRAY_INSTRUCTION = i18n_test_ui.MakeI18nLabelWithClass(
+    'Please insert the SIM card tray', 'instruction-font-size')
+_REMOVE_TRAY_INSTRUCTION = i18n_test_ui.MakeI18nLabelWithClass(
+    'Detected! Please remove the SIM card tray', 'instruction-font-size')
 
 _ID_INSTRUCTION = 'sim-card-tray-test-container'
 _ID_COUNTDOWN_TIMER = 'sim-card-tray-test-timer'
diff --git a/py/test/pytests/raiden_cc2_pull_test.py b/py/test/pytests/raiden_cc2_pull_test.py
index 544769a..0832c85 100644
--- a/py/test/pytests/raiden_cc2_pull_test.py
+++ b/py/test/pytests/raiden_cc2_pull_test.py
@@ -1,5 +1,3 @@
-# -*- mode: python; coding: utf-8 -*-
-#
 # Copyright 2014 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -18,20 +16,18 @@
 import factory_common  # pylint: disable=unused-import
 from cros.factory.device import device_utils
 from cros.factory.test.fixture import bft_fixture
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 
-_TEST_TITLE = test_ui.MakeLabel('Raiden CC2 pull test', u'Raiden CC2 电压测试')
-_DISCONNECT = lambda d: test_ui.MakeLabel(
-    'Raiden port is disconnected in %.1f seconds' % d,
-    u'Raiden port 失去连接 %.1f 秒' % d)
-_DISCONNECT_OP = lambda d: test_ui.MakeLabel(
-    'Please remove Raiden cable in %.1f seconds' % d,
-    u'请在 %.1f 秒内移除 Raiden 线' % d)
-_CONNECT_OP = lambda d: test_ui.MakeLabel(
-    'Please attach Raiden cable in %.1f seconds' % d,
-    u'请在 %.1f 秒内连接 Raiden 线' % d)
+_TEST_TITLE = i18n_test_ui.MakeI18nLabel('Raiden CC2 pull test')
+_DISCONNECT = lambda secs: i18n_test_ui.MakeI18nLabel(
+    'Raiden port is disconnected in {secs:.1f} seconds', secs=secs)
+_DISCONNECT_OP = lambda secs: i18n_test_ui.MakeI18nLabel(
+    'Please remove Raiden cable in {secs:.1f} seconds', secs=secs)
+_CONNECT_OP = lambda secs: i18n_test_ui.MakeI18nLabel(
+    'Please attach Raiden cable in {secs:.1f} seconds', secs=secs)
 _CSS = 'body { font-size: 2em; }'
 
 
diff --git a/py/test/pytests/raiden_cc_flip_check.py b/py/test/pytests/raiden_cc_flip_check.py
index 2ca1df8..cb417d0 100644
--- a/py/test/pytests/raiden_cc_flip_check.py
+++ b/py/test/pytests/raiden_cc_flip_check.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright 2014 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -27,19 +25,18 @@
 from cros.factory.test import countdown_timer
 from cros.factory.test import factory
 from cros.factory.test.fixture import bft_fixture
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 from cros.factory.utils import process_utils
 from cros.factory.utils import sync_utils
 
-_TEST_TITLE = test_ui.MakeLabel('Raiden CC Detect', u'Raiden CC 检查')
-_OPERATION = test_ui.MakeLabel('Flip Raiden cable and plug in again...',
-                               u'将 Raiden port 头反转后再次插入机器...')
-_NO_TIMER = test_ui.MakeLabel('And press Enter key to continue...',
-                              u'并按 Enter 键继续...')
-_WAIT_CONNECTION = test_ui.MakeLabel('Wait DUT to reconnect',
-                                     u'等待 DUT 重新连接')
+_TEST_TITLE = i18n_test_ui.MakeI18nLabel('Raiden CC Detect')
+_OPERATION = i18n_test_ui.MakeI18nLabel(
+    'Flip Raiden cable and plug in again...')
+_NO_TIMER = i18n_test_ui.MakeI18nLabel('And press Enter key to continue...')
+_WAIT_CONNECTION = i18n_test_ui.MakeI18nLabel('Wait DUT to reconnect')
 _CSS = 'body { font-size: 2em; }'
 
 _ID_OPERATION_DIV = 'operation_div'
diff --git a/py/test/pytests/raiden_charge.py b/py/test/pytests/raiden_charge.py
index 024208f..9510b44 100644
--- a/py/test/pytests/raiden_charge.py
+++ b/py/test/pytests/raiden_charge.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright 2014 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -21,6 +19,7 @@
 from cros.factory.device import device_utils
 from cros.factory.test import factory
 from cros.factory.test.fixture import bft_fixture
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.test.utils import stress_manager
@@ -29,18 +28,15 @@
 from cros.factory.utils import time_utils
 from cros.factory.utils import type_utils
 
-_TEST_TITLE = test_ui.MakeLabel('Raiden Charging Test', u'Raiden 充电测试')
-_TESTING_ADB_CONNECTION = test_ui.MakeLabel(
-    'Waiting for ADB device connection...',
-    u'等待机器连线...')
-_TESTING_PROTECT = test_ui.MakeLabel(
-    'Checking Plankton INA current for protection...',
-    u'检查电流保护...')
-_TESTING_CHARGE = lambda v: test_ui.MakeLabel(
-    'Testing battery %dV charging...' % v,
-    u'测试电池 %dV 充电中...' % v)
-_TESTING_DISCHARGE = test_ui.MakeLabel('Testing battery discharging...',
-                                       u'测试电池放电中...')
+_TEST_TITLE = i18n_test_ui.MakeI18nLabel('Raiden Charging Test')
+_TESTING_ADB_CONNECTION = i18n_test_ui.MakeI18nLabel(
+    'Waiting for ADB device connection...')
+_TESTING_PROTECT = i18n_test_ui.MakeI18nLabel(
+    'Checking Plankton INA current for protection...')
+_TESTING_CHARGE = lambda voltage: i18n_test_ui.MakeI18nLabel(
+    'Testing battery {voltage}V charging...', voltage=voltage)
+_TESTING_DISCHARGE = i18n_test_ui.MakeI18nLabel(
+    'Testing battery discharging...')
 _CSS = 'body { font-size: 2em; }'
 
 
diff --git a/py/test/pytests/raiden_display.py b/py/test/pytests/raiden_display.py
index 5eb6873..21eb387 100644
--- a/py/test/pytests/raiden_display.py
+++ b/py/test/pytests/raiden_display.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright 2014 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -21,6 +19,7 @@
 from cros.factory.test import factory
 from cros.factory.test.fixture import bft_fixture
 from cros.factory.test.fixture.dolphin import plankton_hdmi
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.test.utils import evdev_utils
@@ -29,11 +28,10 @@
 from cros.factory.utils import sync_utils
 
 
-_TEST_TITLE = test_ui.MakeLabel('Raiden Display Test', u'Raiden 显示测试')
+_TEST_TITLE = i18n_test_ui.MakeI18nLabel('Raiden Display Test')
 
-_BLACKSCREEN_STR = test_ui.MakeLabel(
-    'Caution: monitor may turn black for a short time.',
-    u'注意: 萤幕可能会有短暂黑屏')
+_BLACKSCREEN_STR = i18n_test_ui.MakeI18nLabel(
+    'Caution: monitor may turn black for a short time.')
 
 _ID_CONTAINER = 'raiden-display-container'
 
@@ -47,19 +45,19 @@
 _WAIT_RETEST_SECS = 2
 
 
-def _GetConnectStr(d):
-  return test_ui.MakeLabel('Connecting BFT display: %s' % d,
-                           u'正在连接 BFT 显示屏: %s' % d)
+def _GetConnectStr(device):
+  return i18n_test_ui.MakeI18nLabel(
+      'Connecting BFT display: {device}', device=device)
 
 
-def _GetVideoStr(d):
-  return test_ui.MakeLabel('BFT display %s is connected. Sending image...' % d,
-                           u'已连接 BFT 显示屏: %s, 正在传送画面' % d)
+def _GetVideoStr(device):
+  return i18n_test_ui.MakeI18nLabel(
+      'BFT display {device} is connected. Sending image...', device=device)
 
 
-def _GetDisconnectStr(d):
-  return test_ui.MakeLabel('Disconnecting BFT display: %s' % d,
-                           u'正在移除 BFT 显示屏: %s' % d)
+def _GetDisconnectStr(device):
+  return i18n_test_ui.MakeI18nLabel(
+      'Disconnecting BFT display: {device}', device=device)
 
 
 class RaidenDisplayTest(unittest.TestCase):
diff --git a/py/test/pytests/read_device_data_from_vpd.py b/py/test/pytests/read_device_data_from_vpd.py
index da9fe32..fee4c06 100644
--- a/py/test/pytests/read_device_data_from_vpd.py
+++ b/py/test/pytests/read_device_data_from_vpd.py
@@ -1,4 +1,3 @@
-# -*- mode: python; coding: utf-8 -*-
 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -13,15 +12,16 @@
 
 import factory_common  # pylint: disable=unused-import
 from cros.factory.device import device_utils
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import shopfloor
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 
 
-_MSG_READING_VPD = lambda vpd_section: test_ui.MakeLabel(
-    'Reading device data from %s VPD...' % vpd_section.upper(),
-    '正在从 %s VPD 读机器资料...' % vpd_section.upper())
+_MSG_READING_VPD = lambda vpd_section: i18n_test_ui.MakeI18nLabel(
+    'Reading device data from {vpd_section} VPD...',
+    vpd_section=vpd_section.upper())
 
 
 class CallShopfloor(unittest.TestCase):
@@ -51,7 +51,7 @@
 
   def runTest(self):
     if self.args.vpd_section not in ['ro', 'rw']:
-      self.fail('Invalid vpd_section:% r, should be %r or %r.' %
+      self.fail('Invalid vpd_section: %r, should be %r or %r.' %
                 (self.args.vpd_section, 'ro', 'rw'))
 
     ui = test_ui.UI()
diff --git a/py/test/pytests/recovery_button.py b/py/test/pytests/recovery_button.py
index aa18c8c..7c697ca 100644
--- a/py/test/pytests/recovery_button.py
+++ b/py/test/pytests/recovery_button.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -10,21 +8,20 @@
 import unittest
 
 import factory_common  # pylint: disable=unused-import
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 from cros.factory.utils import process_utils
 
-_MSG_PRESS_SPACE = test_ui.MakeLabel(
-    'Hit SPACE to start test...',
-    zh=u'按 "空白键" 开始测试...',
-    css_class='recovery-button-info')
+_MSG_PRESS_SPACE = i18n_test_ui.MakeI18nLabelWithClass(
+    'Hit SPACE to start test...', 'recovery-button-info')
 
-_MSG_RECOVERY_BUTTON_TEST = lambda s, t: test_ui.MakeLabel(
-    'Please press recovery button for %.1f seconds (%d seconds remaining).' %
-    (s, t),
-    zh=u'请持续按压恢复按钮 %.1f 秒 (剩余时间: %d 秒).' % (s, t),
-    css_class='recovery-button-info')
+_MSG_RECOVERY_BUTTON_TEST = lambda secs, remain_secs: (
+    i18n_test_ui.MakeI18nLabelWithClass(
+        'Please press recovery button for {secs:.1f} seconds '
+        '({remain_secs} seconds remaining).',
+        'recovery-button-info', secs=secs, remain_secs=remain_secs))
 
 _HTML_RECOVERY_BUTTON = """
 <table style="width: 70%; margin: auto;">
diff --git a/py/test/pytests/removable_storage/removable_storage.py b/py/test/pytests/removable_storage/removable_storage.py
index 60fe190..a23caab 100644
--- a/py/test/pytests/removable_storage/removable_storage.py
+++ b/py/test/pytests/removable_storage/removable_storage.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -27,6 +25,8 @@
 from cros.factory.test.event_log import Log
 from cros.factory.test import factory
 from cros.factory.test.fixture import bft_fixture
+from cros.factory.test.i18n import arg_utils as i18n_arg_utils
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
@@ -58,34 +58,26 @@
 _MILLION = 1000000
 
 _RW_TEST_INSERT_FMT_STR = (
-    lambda t, extra_en, extra_zh: test_ui.MakeLabel(
-        '<br/>'.join(['Insert %s drive for read/write test... %s' % (t,
-                                                                     extra_en),
-                      'WARNING: DATA ON INSERTED MEDIA WILL BE LOST!']),
-        '<br/>'.join([u'插入 %s 存储以进行读写测试... %s' % (t, extra_zh),
-                      u'注意: 插入装置上的资料将会被清除!'])))
-_REMOVE_FMT_STR = lambda t: test_ui.MakeLabel('Remove %s drive...' % t,
-                                              u'提取 %s 存储...' % t)
-_TESTING_FMT_STR = lambda t: test_ui.MakeLabel('Testing %s...' % t,
-                                               u'%s 检查中...' % t)
-_TESTING_RANDOM_RW_FMT_STR = lambda loop, bsize: test_ui.MakeLabel(
-    'Performing r/w test on %d %d-byte random blocks...</br>' % (loop, bsize),
-    u'执行 %d 个 %d 字节区块随机读写测试...</br>' % (loop, bsize))
-_TESTING_SEQUENTIAL_RW_FMT_STR = lambda bsize: test_ui.MakeLabel(
-    'Performing sequential r/w test of %d bytes...</br>' % bsize,
-    u'执行 %d 字节区块连续读写测试...</br>' % bsize)
-_LOCKTEST_INSERT_FMT_STR = (
-    lambda t:
-    test_ui.MakeLabel('Toggle lock switch and insert %s drive again...' % t,
-                      u'切换写保护开关并再次插入 %s 存储...' % t))
-_LOCKTEST_REMOVE_FMT_STR = (
-    lambda t:
-    test_ui.MakeLabel('Remove %s drive and toggle lock switch...' % t,
-                      u'提取 %s 存储并关闭写保护开关...' % t))
-_ERR_REMOVE_TOO_EARLY_FMT_STR = (
-    lambda t:
-    test_ui.MakeLabel('Device removed too early (%s).' % t,
-                      u'太早移除外部储存装置 (%s).' % t))
+    lambda media, extra: i18n_test_ui.MakeI18nLabel(
+        'Insert {media} drive for read/write test... {extra}<br>'
+        'WARNING: DATA ON INSERTED MEDIA WILL BE LOST!',
+        media=media, extra=extra))
+_REMOVE_FMT_STR = lambda media: i18n_test_ui.MakeI18nLabel(
+    'Remove {media} drive...', media=media)
+_TESTING_FMT_STR = lambda media: i18n_test_ui.MakeI18nLabel(
+    'Testing {media}...', media=media)
+_TESTING_RANDOM_RW_FMT_STR = lambda count, bsize: i18n_test_ui.MakeI18nLabel(
+    'Performing r/w test on {count} {bsize}-byte random blocks...<br>',
+    count=count,
+    bsize=bsize)
+_TESTING_SEQUENTIAL_RW_FMT_STR = lambda bsize: i18n_test_ui.MakeI18nLabel(
+    'Performing sequential r/w test of {bsize} bytes...<br>', bsize=bsize)
+_LOCKTEST_INSERT_FMT_STR = (lambda media: i18n_test_ui.MakeI18nLabel(
+    'Toggle lock switch and insert {media} drive again...', media=media))
+_LOCKTEST_REMOVE_FMT_STR = (lambda media: i18n_test_ui.MakeI18nLabel(
+    'Remove {media} drive and toggle lock switch...', media=media))
+_ERR_REMOVE_TOO_EARLY_FMT_STR = (lambda media: i18n_test_ui.MakeI18nLabel(
+    'Device removed too early ({media}).', media=media))
 _ERR_TEST_FAILED_FMT_STR = (
     lambda test_name, target_dev:
     'IO error while running %s test on %s.' % (test_name, target_dev))
@@ -113,8 +105,7 @@
     'BFT fixture failed to %s %s device %s. Reason: %s' % (
         action, test_type, target_dev, reason))
 
-_TEST_TITLE = test_ui.MakeLabel(
-    'Removable Storage Test', u'可移除储存装置测试')
+_TEST_TITLE = i18n_test_ui.MakeI18nLabel('Removable Storage Test')
 
 # Regex used for find execution time from dd output.
 _RE_DD_EXECUTION_TIME = re.compile(
@@ -130,7 +121,7 @@
 
 class RemovableStorageTest(unittest.TestCase):
   """The removable storage factory test."""
-  ARGS = [
+  ARGS = ([
       Arg('media', str, 'Media type'),
       Arg('sysfs_path', str,
           'The expected sysfs path that udev events should '
@@ -159,11 +150,6 @@
       Arg('sequential_block_count', int,
           'Number of blocks to test in sequential read / write test', 1024),
       Arg('perform_locktest', bool, 'Whether to run lock test', False),
-      Arg('extra_prompt_en', (str, unicode),
-          'An extra prompt (in English), e.g., to specify which USB port to '
-          'use', optional=True),
-      Arg('extra_prompt_zh', (str, unicode), 'An extra prompt (in Chinese)',
-          optional=True),
       Arg('timeout_secs', int,
           'Timeout in seconds for the test to wait before it fails',
           default=20),
@@ -183,9 +169,14 @@
           default=None, optional=True),
       Arg('use_busybox_dd', bool,
           'Use busybox dd. This option can be removed when toybox dd is ready.',
-          default=False)]
+          default=False)
+  ] + i18n_arg_utils.BackwardCompatibleI18nArgs(
+      'extra_prompt',
+      'An extra prompt, e.g., to specify which USB port to use',
+      default=''))
 
   def setUp(self):
+    i18n_arg_utils.ParseArg(self, 'extra_prompt')
     self._dut = device_utils.CreateDUTInterface()
     self._ui = test_ui.UI()
     self._template = ui_templates.TwoSections(self._ui)
@@ -683,8 +674,7 @@
     self._template.SetInstruction(
         _RW_TEST_INSERT_FMT_STR(
             self.args.media,
-            self.args.extra_prompt_en or '',
-            self.args.extra_prompt_zh or self.args.extra_prompt_en or ''))
+            self.args.extra_prompt))
     self._state = _STATE_RW_TEST_WAIT_INSERT
     self._template.SetState(_TEST_HTML)
     self.SetState(_IMG_HTML_TAG(self._insertion_image))
diff --git a/py/test/pytests/rf_graphyte/rf_graphyte.py b/py/test/pytests/rf_graphyte/rf_graphyte.py
index b1a663b..7d187c6 100644
--- a/py/test/pytests/rf_graphyte/rf_graphyte.py
+++ b/py/test/pytests/rf_graphyte/rf_graphyte.py
@@ -31,6 +31,7 @@
 from cros.factory.device import device_utils
 from cros.factory.test.args import Arg
 from cros.factory.test import factory
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import shopfloor
 from cros.factory.test import test_ui
 from cros.factory.test import testlog
@@ -64,18 +65,12 @@
   <div id='%s'></div>
 """ % (_ID_MSG_DIV, _ID_DEBUG_DIV)
 
-_MSG_FETCH_CONFIG = test_ui.MakeLabel(
-    'Fetching config files from shopfloor',
-    u'从 shopfloor 下载测试参数',
-    'message')
-_MSG_EXECUTE_GRAPHYTE = test_ui.MakeLabel(
-    'Executing Graphyte',
-    u'執行 Graphyte',
-    'message')
-_MSG_UPLOAD_RESULT = test_ui.MakeLabel(
-    'Uploading result files to shopfloor',
-    u'上傳测试纪录到 shopfloor',
-    'message')
+_MSG_FETCH_CONFIG = i18n_test_ui.MakeI18nLabelWithClass(
+    'Fetching config files from shopfloor', 'message')
+_MSG_EXECUTE_GRAPHYTE = i18n_test_ui.MakeI18nLabelWithClass(
+    'Executing Graphyte', 'message')
+_MSG_UPLOAD_RESULT = i18n_test_ui.MakeI18nLabelWithClass(
+    'Uploading result files to shopfloor', 'message')
 
 class RFGraphyteTest(unittest.TestCase):
 
diff --git a/py/test/pytests/robot_movement.py b/py/test/pytests/robot_movement.py
index 59c5097..5b6d63d 100644
--- a/py/test/pytests/robot_movement.py
+++ b/py/test/pytests/robot_movement.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright 2016 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -7,8 +5,8 @@
 """Task that uses a robot to move the device."""
 
 import logging
-import time
 import threading
+import time
 import unittest
 
 import factory_common  # pylint: disable=unused-import
@@ -16,6 +14,7 @@
 from cros.factory.test.args import Arg
 from cros.factory.test import factory
 from cros.factory.test.fixture import utils as fixture_utils
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import shopfloor
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
@@ -24,41 +23,25 @@
 _TEST_CSS = ('.info {font-size: 2em;}'
              '.warn {font-size: 3em; color: red;}')
 
-_MSG_INIT = test_ui.MakeLabel(
-    'Initializing Robot...',
-    u'正在初始化机器手臂...',
-    'info')
+_MSG_INIT = i18n_test_ui.MakeI18nLabelWithClass('Initializing Robot...', 'info')
 
-_MSG_LOAD = test_ui.MakeLabel(
+_MSG_LOAD = i18n_test_ui.MakeI18nLabelWithClass(
     'Please load DUT onto the robot, connect all cables, '
-    'and press <b>SPACE</b> to continue.',
-    u'将DUT放上机器手臂并接上线路后按下<b>空白键</b>开始。',
-    'info')
+    'and press <b>SPACE</b> to continue.', 'info')
 
-_MSG_PREPARE_MOVEMENT = test_ui.MakeLabel(
-    'Prepare for movement.',
-    u'准备开始移动。',
-    'info')
+_MSG_PREPARE_MOVEMENT = i18n_test_ui.MakeI18nLabelWithClass(
+    'Prepare for movement.', 'info')
 
-_MSG_MOVING_TO_START_POSITION = test_ui.MakeLabel(
-    'Moving to start position...',
-    u'正在移动至起始位置。',
-    'info')
+_MSG_MOVING_TO_START_POSITION = i18n_test_ui.MakeI18nLabelWithClass(
+    'Moving to start position...', 'info')
 
-_MSG_MOVING_TO_LOAD_POSITION = test_ui.MakeLabel(
-    'Moving to LOAD / UNLOAD position...',
-    u'正在移动至卸載位置。',
-    'info')
+_MSG_MOVING_TO_LOAD_POSITION = i18n_test_ui.MakeI18nLabelWithClass(
+    'Moving to LOAD / UNLOAD position...', 'info')
 
-_MSG_COMPUTING = test_ui.MakeLabel(
-    'Computing...',
-    u'校正中...',
-    'info')
+_MSG_COMPUTING = i18n_test_ui.MakeI18nLabelWithClass('Computing...', 'info')
 
-_MSG_PUSHING_RESULT = test_ui.MakeLabel(
-    'Pushing the result...',
-    u'储存结果中...',
-    'info')
+_MSG_PUSHING_RESULT = i18n_test_ui.MakeI18nLabelWithClass(
+    'Pushing the result...', 'info')
 
 
 class RobotMovement(unittest.TestCase):
diff --git a/py/test/pytests/scan/scan.py b/py/test/pytests/scan/scan.py
index c7c2c93..5e043f3 100644
--- a/py/test/pytests/scan/scan.py
+++ b/py/test/pytests/scan/scan.py
@@ -1,4 +1,3 @@
-# -*- mode: python; coding: utf-8 -*-
 # Copyright 2014 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -18,6 +17,10 @@
 from cros.factory.test import event_log
 from cros.factory.test import factory
 from cros.factory.test.fixture import bft_fixture
+from cros.factory.test import i18n
+from cros.factory.test.i18n import _
+from cros.factory.test.i18n import arg_utils as i18n_arg_utils
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import shopfloor
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
@@ -29,15 +32,12 @@
 
 class Scan(unittest.TestCase):
   """The main class for this pytest."""
-  ARGS = [
+  ARGS = (i18n_arg_utils.BackwardCompatibleI18nArgs(
+      'label',
+      'Name of the ID or serial number being scanned, e.g., "MLB serial number"'
+  ) + [
       Arg('aux_table_name', str,
           'Name of the auxiliary table containing the device', optional=True),
-      Arg('label_en', str,
-          'Name of the ID or serial number being scanned, e.g., '
-          '"MLB serial number"'),
-      Arg('label_zh', (str, unicode),
-          'Chinese name of the ID or serial number being scanned '
-          '(defaults to the same as the English label)'),
       Arg('event_log_key', str, 'Key to use for event log', optional=True),
       Arg('shared_data_key', str,
           'Key to use to store in scanned value in shared data',
@@ -71,7 +71,7 @@
       Arg('bft_fixture', dict, bft_fixture.TEST_ARG_HELP, default=None,
           optional=True),
       Arg('barcode_scan_interval_secs', (int, float),
-          'Interval for repeatedly trigger BFT\'s barcode scaner',
+          "Interval for repeatedly trigger BFT's barcode scaner",
           default=2.0),
       Arg('match_the_last_few_chars', int,
           'This is for OP to manually input last few SN chars based on the\n'
@@ -82,13 +82,14 @@
       Arg('value_assigned', str,
           'If not None, use the value to fill the key.', optional=True),
       Arg('reconnect_ghost', bool,
-          'Reconnect ghost to update machine ID', default=False, optional=True)]
+          'Reconnect ghost to update machine ID', default=False, optional=True)
+  ])
 
   def HandleScanValue(self, event):
-    def SetError(label_en, label_zh=None):
-      logging.info('Scan error: %r', label_en)
+    def SetError(label):
+      logging.info('Scan error: %r', label['en-US'])
       self.ui.SetHTML('<span class="test-error">' +
-                      test_ui.MakeLabel(label_en, label_zh) +
+                      i18n_test_ui.MakeI18nLabel(label) +
                       '</span>',
                       id='scan-status')
       self.ui.RunJS('$("scan-value").disabled = false;'
@@ -101,15 +102,15 @@
       scan_value = scan_value.upper()
     esc_scan_value = test_ui.Escape(scan_value)
     if not scan_value:
-      return SetError('The scanned value is empty.',
-                      label_zh=u'掃描編號是空的。')
+      return SetError(_('The scanned value is empty.'))
     if self.args.regexp:
       match = re.match(self.args.regexp, scan_value)
       if not match or match.group(0) != scan_value:
         return SetError(
-            'The scanned value "%s" does not match '
-            'the expected format.' % esc_scan_value,
-            label_zh=u'所掃描的編號「%s」格式不對。' % esc_scan_value)
+            i18n.StringFormat(
+                _('The scanned value "{value}" does not match '
+                  'the expected format.'),
+                value=esc_scan_value))
 
     if self.args.aux_table_name:
       try:
@@ -118,18 +119,18 @@
       except shopfloor.ServerFault:
         logging.exception('select_aux_data failed')
         return SetError(
-            'The scanned value "%s" is not a known %s.' % (
-                esc_scan_value, self.args.label_en),
-            label_zh=u'所掃描的編號「%s」不是已知的%s。' % (
-                esc_scan_value, self.args.label_zh))
+            i18n.StringFormat(
+                _('The scanned value "{value}" is not a known {label}.'),
+                value=esc_scan_value, label=self.args.label))
       except socket.error as e:
         logging.exception('select_aux_data failed')
         return SetError(
-            'Unable to contact shopfloor server: %s' % e,
-            label_zh=u'連不到 shopfloor server: %s' % e)
+            i18n.StringFormat(
+                _('Unable to contact shopfloor server: {exception}'),
+                exception=e))
       except:  # pylint: disable=bare-except
         logging.exception('select_aux_data failed')
-        return SetError(debug_utils.FormatExceptionOnly())
+        return SetError(i18n.NoTranslation(debug_utils.FormatExceptionOnly()))
 
     if self.args.event_log_key:
       event_log.Log('scan', key=self.args.event_log_key, value=scan_value)
@@ -158,20 +159,18 @@
         # can't fake it.
         esc_expected_value = test_ui.Escape(expected_value or 'None')
         return SetError(
-            'The scanned value "%s" does not match '
-            'the expected value'
-            '<span class=test-engineering-mode-only> "%s"</span>.' % (
-                esc_scan_value, esc_expected_value),
-            label_zh=(
-                u'所掃描的編號「%s」不搭配所期望的編號'
-                u'<span class=test-engineering-mode-only>「%s」</span>。' % (
-                    esc_scan_value, esc_expected_value)))
+            i18n.StringFormat(
+                _('The scanned value "{value}" does not match '
+                  'the expected value <span class=test-engineering-mode-only>'
+                  '"{expected_value}"</span>.'),
+                value=esc_scan_value, expected_value=esc_expected_value))
 
     if self.args.rw_vpd_key or self.args.ro_vpd_key:
       self.ui.SetHTML(
-          ' '.join([test_ui.MakeLabel('Writing to VPD. Please wait...',
-                                      u'正在写到 VPD,请稍等...'),
-                    test_ui.SPINNER_HTML_16x16]),
+          ' '.join([
+              i18n_test_ui.MakeI18nLabel('Writing to VPD. Please wait...'),
+              test_ui.SPINNER_HTML_16x16
+          ]),
           id='scan-status')
       try:
         if self.args.rw_vpd_key:
@@ -187,6 +186,7 @@
     self.ui.Pass()
 
   def setUp(self):
+    i18n_arg_utils.ParseArg(self, 'label')
     self.dut = device_utils.CreateDUTInterface()
     self.ui = test_ui.UI()
     self.auto_scan_timer = None
@@ -224,22 +224,13 @@
   def runTest(self):
     template = ui_templates.OneSection(self.ui)
 
-    if not self.args.label_zh:
-      self.args.label_zh = self.args.label_en
-
-    # A workaround that some existing test lists do not use unicode
-    # for Chinese string.
-    if type(self.args.label_zh) is str:
-      self.args.label_zh = unicode(self.args.label_zh, encoding='utf-8')
-
-    template.SetTitle(test_ui.MakeLabel(
-        'Scan %s' % self.args.label_en.title(),
-        u'扫描%s' % self.args.label_zh))
+    template.SetTitle(
+        i18n_test_ui.MakeI18nLabel('Scan {label}', label=self.args.label))
 
     template.SetState(
-        test_ui.MakeLabel(
-            'Please scan the %s and press ENTER.' % self.args.label_en,
-            u'请扫描%s後按下 ENTER。' % self.args.label_zh) +
+        i18n_test_ui.MakeI18nLabel(
+            'Please scan the {label} and press ENTER.',
+            label=self.args.label) +
         '<br><input id="scan-value" type="text" size="20">'
         '<br>&nbsp;'
         '<p id="scan-status">&nbsp;')
diff --git a/py/test/pytests/select_aux_field.py b/py/test/pytests/select_aux_field.py
index 47b8f2a..916993c 100644
--- a/py/test/pytests/select_aux_field.py
+++ b/py/test/pytests/select_aux_field.py
@@ -1,4 +1,3 @@
-# -*- mode: python; coding: utf-8 -*-
 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -9,6 +8,10 @@
 
 import factory_common  # pylint: disable=unused-import
 from cros.factory.test import event_log
+from cros.factory.test import i18n
+from cros.factory.test.i18n import _
+from cros.factory.test.i18n import arg_utils as i18n_arg_utils
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import shopfloor
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
@@ -23,12 +26,9 @@
   shopfloor aux_data with the specified aux table name, id, and col name.
   """
 
-  ARGS = [
-      Arg('label_en', str, 'Name of the model being selected'),
-      Arg('label_zh', str,
-          'Chinese name of the model being selected '
-          '(defaults to the same as the English label)',
-          optional=True),
+  ARGS = i18n_arg_utils.BackwardCompatibleI18nArgs(
+      'label', 'Name of the model being selected'
+  ) + [
       Arg('event_log_key', str, 'Key to use for event log', optional=True),
       Arg('aux_table_name', str, 'Name of the auxiliary table'),
       Arg('aux_id', str, 'Name of the auxiliary ID'),
@@ -38,15 +38,14 @@
           'stored.')]
 
   def HandleSelectValue(self, event):
-    def SetError(label_en, label_zh=None):
-      logging.info('Select error: %r', label_en)
-      self.ui.SetHTML(test_ui.MakeLabel(label_en, label_zh),
-                      id='select-error')
+    def SetError(label):
+      logging.info('Select error: %r', label['en-US'])
+      self.ui.SetHTML(i18n_test_ui.MakeI18nLabel(label), id='select-error')
 
     select_value = event.data.strip()
     logging.debug('Selected value: %s', select_value)
     if not select_value:
-      return SetError('No selection.', '未选择。')
+      return SetError(_('No selection.'))
 
     try:
       shopfloor.save_aux_data(
@@ -54,7 +53,7 @@
           {self.args.col_name: self.args.choices.get(select_value)})
     except:  # pylint: disable=bare-except
       logging.exception('save_aux_data failed')
-      return SetError(debug_utils.FormatExceptionOnly())
+      return SetError(i18n.NoTranslation(debug_utils.FormatExceptionOnly()))
 
     if self.args.event_log_key:
       event_log.Log('select', key=self.args.event_log_key, value=select_value)
@@ -62,17 +61,14 @@
     self.ui.Pass()
 
   def setUp(self):
+    i18n_arg_utils.ParseArg(self, 'label')
     self.ui = test_ui.UI()
 
   def runTest(self):
     template = ui_templates.OneSection(self.ui)
 
-    if not self.args.label_zh:
-      self.args.label_zh = self.args.label_en
-
-    template.SetTitle(test_ui.MakeLabel(
-        'Select %s' % self.args.label_en.title(),
-        '选择%s' % self.args.label_zh))
+    template.SetTitle(
+        i18n_test_ui.MakeI18nLabel('Select {label}', label=self.args.label))
 
     # Display choices as radio buttons.
     radio_button_html = ''
@@ -85,11 +81,9 @@
           (choice, i) +
           '<label for="choice_%d">%s</label><br>' % (i, choice))
     template.SetState(
-        test_ui.MakeLabel(
-            'Please select the %s and press ENTER.' % self.args.label_en,
-            '请选择%s後按下 ENTER。' % (
-                self.args.label_zh or self.args.label_en)) + '<br>' +
-        radio_button_html + '<br>&nbsp;'
+        i18n_test_ui.MakeI18nLabel(
+            'Please select the {label} and press ENTER.',
+            label=self.args.label) + '<br>' + radio_button_html + '<br>&nbsp;'
         '<p id="select-error" class="test-error">&nbsp;')
 
     # Handle selected value when Enter pressed.
diff --git a/py/test/pytests/select_components.py b/py/test/pytests/select_components.py
index c8c150f..3cfc090 100644
--- a/py/test/pytests/select_components.py
+++ b/py/test/pytests/select_components.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -15,14 +13,15 @@
 from cros.factory.hwid.v3 import database
 from cros.factory.hwid.v3 import hwid_utils
 from cros.factory.test import factory
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import shopfloor
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 from cros.factory.utils import string_utils
 
-_MESSAGE_SELECT = test_ui.MakeLabel('Select Components:', u'选择元件:',
-                                    'msg-font-size')
+_MESSAGE_SELECT = i18n_test_ui.MakeI18nLabelWithClass('Select Components:',
+                                                      'msg-font-size')
 
 _TEST_DEFAULT_CSS = '.msg-font-size {font-size: 2em;}'
 _SELECT_BOX_STYLE = ('font-size: 1.5em; background-color: white; '
@@ -32,7 +31,7 @@
 _SELECTION_PER_PAGE = 10
 _EVENT_SUBTYPE_SELECT_COMP = 'Select-Components'
 
-_TEST_TITLE = test_ui.MakeLabel('Select Components', u'选择元件')
+_TEST_TITLE = i18n_test_ui.MakeI18nLabel('Select Components')
 
 
 class SelectComponentTest(unittest.TestCase):
diff --git a/py/test/pytests/sensor_movement.py b/py/test/pytests/sensor_movement.py
index a12b9a4..35c4532 100644
--- a/py/test/pytests/sensor_movement.py
+++ b/py/test/pytests/sensor_movement.py
@@ -43,6 +43,8 @@
 import factory_common  # pylint: disable=unused-import
 from cros.factory.device import device_utils
 from cros.factory.test import factory_task
+from cros.factory.test import i18n
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
@@ -50,10 +52,10 @@
 from cros.factory.utils import type_utils
 
 
-_MSG_PASS = test_ui.MakeLabel('PASS', u'成功', 'test-pass')
-_MSG_FAIL = test_ui.MakeLabel('FAIL', u'失败', 'test-fail')
+_MSG_PASS = i18n_test_ui.MakeI18nLabelWithClass('PASS', 'test-pass')
+_MSG_FAIL = i18n_test_ui.MakeI18nLabelWithClass('FAIL', 'test-fail')
 
-_BR = '<br/>'
+_BR = '<br>'
 
 _CSS = """
   .test-info {font-size: 2em;}
@@ -125,11 +127,14 @@
           'and "magnetometer".',
           optional=False),
       Arg('sub_tests', list,
-          'A list of tuples of the format'
+          'A list of tuples of the format '
+          '(instruction, expected_value) or '
           '(instruction_en, instruction_zh, expected_value), which tells '
           'operator to move the dut, and checks the sensor output.\n'
           '\n'
           'The fields are:\n'
+          '- instruction: instruction on how to move the dut, would be passed '
+          'to i18n.Translated.\n'
           '- instruction_en: (str or unicode) instruction on how to move the '
           'dut in English.\n'
           '- instruction_zh: (str or unicode) instruction on how to move the '
@@ -159,17 +164,23 @@
     self._task_manager = None
 
   def runTest(self):
-    task_list = [SensorMovementTask(self,
-                                    self.dut,
-                                    self.args.sensor_type,
-                                    test_ui.MakeLabel(test[0],
-                                                      test[1],
-                                                      'test-info'),
-                                    test[2],
-                                    self.args.tolerance,
-                                    self.args.capture_count,
-                                    self.args.timeout_secs,
-                                    self.args.controller_options)
-                 for test in self.args.sub_tests]
+    task_list = []
+    for test in self.args.sub_tests:
+      if len(test) == 3:
+        # TODO(pihsun): This is to maintain backward compatibility. Should be
+        #               removed after test lists are migrated to new format.
+        test = ({'en-US': test[0], 'zh-CN': test[1]}, test[2])
+      label = i18n_test_ui.MakeI18nLabelWithClass(
+          i18n.Translated(test[0], translate=False), 'test-info')
+      task_list.append(SensorMovementTask(
+          self,
+          self.dut,
+          self.args.sensor_type,
+          label,
+          test[1],
+          self.args.tolerance,
+          self.args.capture_count,
+          self.args.timeout_secs,
+          self.args.controller_options))
     self._task_manager = factory_task.FactoryTaskManager(self.ui, task_list)
     self._task_manager.Run()
diff --git a/py/test/pytests/shutdown/shutdown.py b/py/test/pytests/shutdown/shutdown.py
index a89814f..ad6902a 100644
--- a/py/test/pytests/shutdown/shutdown.py
+++ b/py/test/pytests/shutdown/shutdown.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -17,6 +15,8 @@
 from cros.factory.test import event as test_event
 from cros.factory.test import event_log
 from cros.factory.test import factory
+from cros.factory.test.i18n import _
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import state
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
@@ -27,25 +27,27 @@
 
 # File that suppresses reboot if present (e.g., for development).
 NO_REBOOT_FILE = '/var/log/factory.noreboot'
-_DICT_OPERATION = {
-    'reboot': u'重新启动',
-    'full_reboot': u'深度重启',
-    'halt': u'关机'
+_DICT_OPERATION_LABEL = {
+    'reboot': _('reboot'),
+    'full_reboot': _('full reboot'),
+    'halt': _('halt')
 }
-_SHUTDOWN_COMMENCING_MSG = lambda operation, delay: test_ui.MakeLabel(
-    'System is going to %s in %d seconds.' % (operation, delay),
-    u'系统将在 %d 秒后%s.' %
-    (delay, _DICT_OPERATION.get(operation, operation)))
-_REMOTE_SHUTDOWN_PROGRESS_MSG = lambda operation, delay: test_ui.MakeLabel(
-    'Remote DUT is performing %s, timeout in %d seconds.' % (operation, delay),
-    u'远端测试装置将于 %d 秒內%s.' % (
-        delay, _DICT_OPERATION.get(operation, operation)))
-_SHUTDOWN_COMPLETE_MSG = lambda operation: test_ui.MakeLabel(
-    'Verifying system state after %s' % operation,
-    u'%s后验证系统状态' % _DICT_OPERATION.get(operation, operation))
-_TEST_TITLE = lambda operation: test_ui.MakeLabel(
-    'Shutdown Test (%s)' % operation,
-    u'关机测试 (%s)' % _DICT_OPERATION.get(operation, operation))
+_SHUTDOWN_COMMENCING_MSG = lambda operation, delay: (
+    i18n_test_ui.MakeI18nLabel(
+        'System is going to {operation} in {delay} seconds.',
+        operation=_DICT_OPERATION_LABEL.get(operation, operation),
+        delay=delay))
+_REMOTE_SHUTDOWN_PROGRESS_MSG = lambda operation, delay: (
+    i18n_test_ui.MakeI18nLabel(
+        'Remote DUT is performing {operation}, timeout in {delay} seconds.',
+        operation=_DICT_OPERATION_LABEL.get(operation, operation),
+        delay=delay))
+_SHUTDOWN_COMPLETE_MSG = lambda operation: i18n_test_ui.MakeI18nLabel(
+    'Verifying system state after {operation}',
+    operation=_DICT_OPERATION_LABEL.get(operation, operation))
+_TEST_TITLE = lambda operation: i18n_test_ui.MakeI18nLabel(
+    'Shutdown Test ({operation})',
+    operation=_DICT_OPERATION_LABEL.get(operation, operation))
 _CSS = 'body { font-size: 2em; }'
 
 
diff --git a/py/test/pytests/simple_battery.py b/py/test/pytests/simple_battery.py
index 4200f81..8ed20cd 100644
--- a/py/test/pytests/simple_battery.py
+++ b/py/test/pytests/simple_battery.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -20,6 +18,7 @@
 import factory_common  # pylint: disable=unused-import
 from cros.factory.device import device_utils
 from cros.factory.test import factory
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.test.utils import stress_manager
@@ -28,13 +27,11 @@
 from cros.factory.utils import time_utils
 
 
-_TEST_TITLE = test_ui.MakeLabel('Simple Battery Test', u'简单电池测试')
-_UNPLUG_AC = test_ui.MakeLabel('Unplug AC to proceed', u'拔除 AC 电源')
-_PLUG_AC = test_ui.MakeLabel('Plug AC to proceed', u'插上 AC 电源')
-_TESTING_CHARGE = test_ui.MakeLabel('Testing battery charge...',
-                                    u'测试电池充电中...')
-_TESTING_DISCHARGE = test_ui.MakeLabel('Testing battery discharge...',
-                                       u'测试电池放电中...')
+_TEST_TITLE = i18n_test_ui.MakeI18nLabel('Simple Battery Test')
+_UNPLUG_AC = i18n_test_ui.MakeI18nLabel('Unplug AC to proceed')
+_PLUG_AC = i18n_test_ui.MakeI18nLabel('Plug AC to proceed')
+_TESTING_CHARGE = i18n_test_ui.MakeI18nLabel('Testing battery charge...')
+_TESTING_DISCHARGE = i18n_test_ui.MakeI18nLabel('Testing battery discharge...')
 _CSS = 'body { font-size: 2em; }'
 
 
@@ -91,7 +88,7 @@
     while time_utils.MonotonicTime() < end_time:
       sampled_current.append(self._dut.power.GetBatteryCurrent())
       time.sleep(self.args.current_sampling_period_secs)
-    logging.info('Sampled battery current: %s', str(sampled_current))
+    logging.info('Sampled battery current: %s', sampled_current)
     return sampled_current
 
   def TestCharge(self, duration_secs):
diff --git a/py/test/pytests/smart_check_fw_version.py b/py/test/pytests/smart_check_fw_version.py
index 3d5e806..e5f8b87 100644
--- a/py/test/pytests/smart_check_fw_version.py
+++ b/py/test/pytests/smart_check_fw_version.py
@@ -1,4 +1,3 @@
-# -*- mode: python; coding: utf-8 -*-
 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -15,6 +14,7 @@
 import unittest
 
 import factory_common  # pylint: disable=unused-import
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
@@ -46,17 +46,12 @@
 
     ui = test_ui.UI()
     template = ui_templates.OneSection(ui)
-    template.SetTitle(test_ui.MakeLabel(
-        'SSD Firmware Version Incorrect',
-        'SSD 韧体版本不对'))
+    template.SetTitle(
+        i18n_test_ui.MakeI18nLabel('SSD Firmware Version Incorrect'))
     template.SetState(
         '<div class=test-status-failed style="font-size: 150%">' +
-        test_ui.MakeLabel(
-            'The SSD firmware version (%s) is incorrect. '
-            '<br>Please run the SSD firmware update tool.' %
-            test_ui.Escape(fw_version),
-            'SSD 韧体版(%s)版本不对。'
-            '<br>必须更新 SSD 韧体并重新安装工厂测试软件。' %
-            test_ui.Escape(fw_version)) +
-        '</div>')
+        i18n_test_ui.MakeI18nLabel(
+            'The SSD firmware version ({fw_version}) is incorrect. '
+            '<br>Please run the SSD firmware update tool.',
+            fw_version=test_ui.Escape(fw_version)) + '</div>')
     ui.Run()  # Forever
diff --git a/py/test/pytests/spatial_sensor_calibration.py b/py/test/pytests/spatial_sensor_calibration.py
index cbe2eb3..2d0fc5a 100644
--- a/py/test/pytests/spatial_sensor_calibration.py
+++ b/py/test/pytests/spatial_sensor_calibration.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright 2015 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -31,13 +29,17 @@
 import factory_common  # pylint: disable=unused-import
 from cros.factory.device import device_utils
 from cros.factory.test import factory
+from cros.factory.test import i18n
+from cros.factory.test.i18n import _
+from cros.factory.test.i18n import arg_utils as i18n_arg_utils
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 from cros.factory.utils import sync_utils
 
 
-DEFAULT_NAME = ('Accelerometer', u'加速度计')
+DEFAULT_NAME = _('Accelerometer')
 DEFAULT_RAW_ENTRY_TEMPLATE = 'in_accel_%s_raw'
 DEFAULT_CALIBBIAS_ENTRY_TEMPLATE = 'in_accel_%s_calibbias'
 DEFAULT_VPD_ENTRY_TEMPLATE = 'in_accel_%s_base_calibbias'
@@ -56,8 +58,8 @@
   ARGS = [
       Arg('timeout_secs', int, 'Timeout in seconds when waiting for device.',
           default=60),
-      Arg('sensor_name', tuple, 'English and simplified Chinese name of the '
-          'sensor to calibrate.', default=DEFAULT_NAME),
+      i18n_arg_utils.I18nArg('sensor_name', 'name of the sensor to calibrate.',
+                             default=DEFAULT_NAME, accept_tuple=True),
       Arg('device_name', str, 'The "name" atribute of the sensor'),
       Arg('device_location', str, 'The "location" atribute of the sensor'),
       Arg('raw_entry_template', str,
@@ -79,6 +81,7 @@
   ]
 
   def setUp(self):
+    i18n_arg_utils.ParseArg(self, 'sensor_name')
     self._dut = device_utils.CreateDUTInterface()
     self._device_path = None
     for path in self._dut.Glob('/sys/bus/iio/devices/iio:device*'):
@@ -93,7 +96,7 @@
         self._device_path = path
     if self._device_path is None:
       raise factory.FactoryTestFailure('%s at %s not found' %
-                                       (self.args.sensor_name[0],
+                                       (self.args.sensor_name['en-US'],
                                         self.args.device_location))
 
     self._ui = test_ui.UI(css=CSS)
@@ -121,27 +124,26 @@
     self.WaitForDevice()
     self.VerifyDevicePosition()
 
-    self._template.SetState(test_ui.MakeLabel(
-        'Calibrating %s...' % self.args.sensor_name[0],
-        u'正在校正 %s...' % self.args.sensor_name[1]))
+    self._template.SetState(
+        i18n_test_ui.MakeI18nLabel(
+            'Calibrating {sensor_name}...', sensor_name=self.args.sensor_name))
 
     self.EnableAutoCalibration(self._device_path)
     self.RetrieveCalibbiasAndWriteVPD()
     self._ui.Pass()
 
   def Prompt(self, prev_fail=False):
-    prompt_en = '<div class="error">%s</div><br/>%s' % (
-        'Device not in position' if prev_fail else '',
-        'Please put the device in face-up position (press Enter to continue)')
-    prompt_zh = '<div class="error">%s</div><br/>%s' % (
-        u'装置位置不正确' if prev_fail else '',
-        u'请将装置面向上(按 Enter 继续)')
+    prompt = i18n.StringJoin(
+        '<div class="error">',
+        _('Device not in position') if prev_fail else '',
+        '</div><br>',
+        _('Please put the device in face-up position'
+          ' (press Enter to continue)'))
 
-    self._template.SetState(test_ui.MakeLabel(prompt_en, prompt_zh))
+    self._template.SetState(i18n_test_ui.MakeI18nLabel(prompt))
 
   def WaitForDevice(self):
-    self._template.SetState(test_ui.MakeLabel('Waiting for device...',
-                                              u'正在等待装置...'))
+    self._template.SetState(i18n_test_ui.MakeI18nLabel('Waiting for device...'))
     sync_utils.WaitFor(self._dut.IsReady, self.args.timeout_secs)
     if not self._dut.IsReady():
       self.fail('failed to find deivce')
@@ -179,8 +181,8 @@
     cmd = ['vpd']
 
     for axis in ['x', 'y', 'z']:
-      self._template.SetState(test_ui.MakeLabel('Writing calibration data...',
-                                                u'正在写入校正结果...'))
+      self._template.SetState(
+          i18n_test_ui.MakeI18nLabel('Writing calibration data...'))
       calibbias_key = self.args.calibbias_entry_template % axis
       vpd_key = self.args.vpd_entry_template % axis
       value = self._dut.ReadFile(self._dut.path.join(self._device_path, calibbias_key))
diff --git a/py/test/pytests/start/start.py b/py/test/pytests/start/start.py
index 419c059..19164da 100644
--- a/py/test/pytests/start/start.py
+++ b/py/test/pytests/start/start.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -18,7 +16,6 @@
 
 import logging
 import os
-import re
 import socket
 import sys
 import time
@@ -26,19 +23,23 @@
 
 import factory_common  # pylint: disable=unused-import
 from cros.factory.device import device_utils
+from cros.factory.test.event import Event
+from cros.factory.test.event_log import Log
 from cros.factory.test import factory
+from cros.factory.test.factory_task import FactoryTask
+from cros.factory.test.factory_task import FactoryTaskManager
+from cros.factory.test.i18n import _
+from cros.factory.test.i18n import arg_utils as i18n_arg_utils
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import shopfloor
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
-from cros.factory.test.event import Event
-from cros.factory.test.event_log import Log
-from cros.factory.test.factory_task import FactoryTask, FactoryTaskManager
-from cros.factory.utils import process_utils
 from cros.factory.utils.arg_utils import Arg
+from cros.factory.utils import process_utils
 from cros.factory.utils.type_utils import Enum
 
 
-_TEST_TITLE = test_ui.MakeLabel('Start Factory Test', u'开始工厂测试')
+_TEST_TITLE = i18n_test_ui.MakeI18nLabel('Start Factory Test')
 
 _CSS = """
 .start-font-size {
@@ -59,46 +60,26 @@
 """
 
 # Messages for tasks
-_MSG_INSTALL_INCOMPLETE = test_ui.MakeLabel(
-    '<br/>'.join([
-        'Factory install process did not complete. Auto-testing stopped.<br/>',
-        'Please install the factory test image using the mini-Omaha server',
-        'rather than booting from a USB drive.</br>']),
-    '<br/>'.join([
-        u'安装过程中失败, 停止自動測試。<br/>',
-        u'請使用完整的 mini-Omaha 伺服器安裝測試程式,',
-        u'不要直接從 USB 碟開機執行。<br/>']),
-    'start-font-size test-error')
-_MSG_TASK_POWER = test_ui.MakeLabel(
-    'Plug in external power to continue.',
-    u'请插上外接电源以继续。',
-    'start-font-size')
-_MSG_TASK_SPACE = test_ui.MakeLabel(
-    'Hit SPACE to start testing...',
-    u'按 "空白键" 开始测试...',
-    'start-font-size')
-_MSG_NO_SHOP_FLOOR_SERVER_URL = test_ui.MakeLabel(
-    '<br/>'.join([
-        'No shop floor server URL. Auto-testing stopped.<br/>',
-        'Please install the factory test image using the mini-Omaha server',
-        'rather than booting from a USB drive.</br>',
-        'For debugging or development, use the listed hot-keys to start',
-        'individual tests.']),
-    '<br/>'.join([
-        u'未指定 shop floor 服务器位址,停止自动测试。<br/>',
-        u'请使用完整的 mini-Omaha 服务器安装测试程式,',
-        u'不要直接从 USB 碟开机执行。<br/>',
-        u'若想除错或执行部份测试,请直接按下对应热键。']),
-    'start-font-size test-error')
-_MSG_READING_VPD_SERIAL = test_ui.MakeLabel(
-    'Reading VPD...', u'讀取 VPD 中...', 'start-font-size')
-_MSG_CONTACTING_SERVER = test_ui.MakeLabel(
-    'Contacting shop floor server...', u'正在和 shop floor server 联络...',
-    r'start-contacting-server')
-_MSG_INIT_SHARED_DATA = test_ui.MakeLabel(
-    'Initialize some shared data...',
-    u'重设旧有共用资料...',
-    'start-font-size')
+_MSG_INSTALL_INCOMPLETE = i18n_test_ui.MakeI18nLabelWithClass(
+    'Factory install process did not complete. Auto-testing stopped.<br><br>'
+    'Please install the factory test image using the mini-Omaha server<br>'
+    'rather than booting from a USB drive.<br>', 'start-font-size test-error')
+_MSG_TASK_POWER = i18n_test_ui.MakeI18nLabelWithClass(
+    'Plug in external power to continue.', 'start-font-size')
+_MSG_TASK_SPACE = i18n_test_ui.MakeI18nLabelWithClass(
+    'Hit SPACE to start testing...', 'start-font-size')
+_MSG_NO_SHOP_FLOOR_SERVER_URL = i18n_test_ui.MakeI18nLabelWithClass(
+    'No shop floor server URL. Auto-testing stopped.<br><br>'
+    'Please install the factory test image using the mini-Omaha server<br>'
+    'rather than booting from a USB drive.<br><br>'
+    'For debugging or development, use the listed hot-keys to start<br>'
+    'individual tests.', 'start-font-size test-error')
+_MSG_READING_VPD_SERIAL = i18n_test_ui.MakeI18nLabelWithClass('Reading VPD...',
+                                                              'start-font-size')
+_MSG_CONTACTING_SERVER = i18n_test_ui.MakeI18nLabelWithClass(
+    'Contacting shop floor server...', r'start-contacting-server')
+_MSG_INIT_SHARED_DATA = i18n_test_ui.MakeI18nLabelWithClass(
+    'Initialize some shared data...', 'start-font-size')
 
 # Javascripts and HTML for tasks
 _EVENT_SUBTYPE_SHOP_FLOOR = 'Start-Serial'
@@ -196,8 +177,9 @@
 
     self._test.ui.AddEventHandler(_EVENT_SUBTYPE_SHOP_FLOOR,
                                   self.ValidateSerialNumber)
-    prompt_en, prompt_zh = self._test.args.prompt
-    prompt_html = test_ui.MakeLabel(prompt_en, prompt_zh, 'start-font-size')
+    prompt = self._test.args.prompt
+    prompt_html = i18n_test_ui.MakeI18nLabel(
+        prompt, _css_class='start-font-size')
     self._test.template.SetState(prompt_html + _HTML_SHOP_FLOOR)
     self._test.ui.RunJS(_JS_SHOP_FLOOR)
 
@@ -313,14 +295,15 @@
           'A string or list of strings indicating a set of VPDs that are used '
           'as the key to fetch data from shop floor proxy.',
           default=None, optional=True),
-      Arg('prompt', tuple,
-          'Message to show to the operator when prompting for input.',
-          default=('Enter valid serial number:<br/>',
-                   u'请输入有效的序号:<br/>'), optional=True),
+      i18n_arg_utils.I18nArg(
+          'prompt', 'Message to show to the operator when prompting for input.',
+          default=_('Enter valid serial number:<br>'),
+          accept_tuple=True),
       Arg('init_shared_data', dict, 'the shared data to initialize',
           default={}, optional=True)]
 
   def setUp(self):
+    i18n_arg_utils.ParseArg(self, 'prompt')
     self.dut = device_utils.CreateDUTInterface()
     self._task_list = []
     self.ui = test_ui.UI()
diff --git a/py/test/pytests/station_entry.py b/py/test/pytests/station_entry.py
index e26bc72..3ebe125 100644
--- a/py/test/pytests/station_entry.py
+++ b/py/test/pytests/station_entry.py
@@ -1,6 +1,4 @@
 #!/usr/bin/env python
-# -*- coding: UTF-8 -*-
-#
 # Copyright 2015 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -18,6 +16,7 @@
 from cros.factory.device import device_utils
 from cros.factory.test import countdown_timer
 from cros.factory.test import factory
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
@@ -34,8 +33,8 @@
 }
 """
 
-_TITLE_START = test_ui.MakeLabel('Start Station Test', u'开始测试')
-_TITLE_END = test_ui.MakeLabel('End Station Test', u'结束测试')
+_TITLE_START = i18n_test_ui.MakeI18nLabel('Start Station Test')
+_TITLE_END = i18n_test_ui.MakeI18nLabel('End Station Test')
 
 _ID_MSG_DIV = 'msg'
 _ID_COUNTDOWN_DIV = 'countdown'
@@ -45,35 +44,23 @@
 <div id='%s'></div>
 """ % (_ID_MSG_DIV, _ID_COUNTDOWN_DIV)
 
-_MSG_INSERT = test_ui.MakeLabel(
-    'Please attach DUT.',
-    u'INSERT 请插入测试装置。',
-    'prompt')
+_MSG_INSERT = i18n_test_ui.MakeI18nLabelWithClass(
+    'Please attach DUT.', 'prompt')
 
-_MSG_PRESS_SPACE = test_ui.MakeLabel(
-    'Press SPACE to start the test.',
-    u'请按空白键开始测试。',
-    'prompt')
+_MSG_PRESS_SPACE = i18n_test_ui.MakeI18nLabelWithClass(
+    'Press SPACE to start the test.', 'prompt')
 
-_MSG_PRESS_SPACE_TO_END = test_ui.MakeLabel(
-    'Press SPACE to end the test.',
-    u'请按空白键结束测试。',
-    'prompt')
+_MSG_PRESS_SPACE_TO_END = i18n_test_ui.MakeI18nLabelWithClass(
+    'Press SPACE to end the test.', 'prompt')
 
-_MSG_SEND_RESULT = test_ui.MakeLabel(
-    'Sending test results to shopfloor...',
-    u'SENDING 传送测试结果给服务器...',
-    'prompt')
+_MSG_SEND_RESULT = i18n_test_ui.MakeI18nLabelWithClass(
+    'Sending test results to shopfloor...', 'prompt')
 
-_MSG_REMOVE_DUT = test_ui.MakeLabel(
-    'Please remove DUT.',
-    u'REMOVE 请移除测试装置。',
-    'prompt')
+_MSG_REMOVE_DUT = i18n_test_ui.MakeI18nLabelWithClass(
+    'Please remove DUT.', 'prompt')
 
-_MSG_RESTART_TESTS = test_ui.MakeLabel(
-    'Restarting all tests...',
-    u'RESTARTING 测试结束,正在重设测试列表...',
-    'prompt')
+_MSG_RESTART_TESTS = i18n_test_ui.MakeI18nLabelWithClass(
+    'Restarting all tests...', 'prompt')
 
 
 class StationEntry(unittest.TestCase):
diff --git a/py/test/pytests/stylus.py b/py/test/pytests/stylus.py
index d753c42..535b38f 100644
--- a/py/test/pytests/stylus.py
+++ b/py/test/pytests/stylus.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 # Copyright 2016 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -7,6 +6,7 @@
 
 import factory_common  # pylint: disable=unused-import
 from cros.factory.external import evdev
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.test.utils import evdev_utils
@@ -18,13 +18,10 @@
 
 _MSG_PROMPT_CSS_CLASS = 'stylus-test-css-class'
 _MSG_PROMPT_CSS = '.%s { font-size: 2em; }' % _MSG_PROMPT_CSS_CLASS
-_MSG_PROMPT = test_ui.MakeLabel(
+_MSG_PROMPT = i18n_test_ui.MakeI18nLabelWithClass(
     'Please draw a line with stylus from bottom left corner to top right '
     'corner. Stay between the two red lines.<br>'
-    'Press SPACE to start; Esc to fail.',
-    u'请使用触控笔从左下方画至右上角,不要超出红线区域。<br>'
-    u'按空白键开始测试; Esc 键标记失败',
-    _MSG_PROMPT_CSS_CLASS)
+    'Press SPACE to start; Esc to fail.', _MSG_PROMPT_CSS_CLASS)
 
 
 class _AbsInfo(object):
diff --git a/py/test/pytests/summary/summary.py b/py/test/pytests/summary/summary.py
index 7176b86..2f6d439 100644
--- a/py/test/pytests/summary/summary.py
+++ b/py/test/pytests/summary/summary.py
@@ -1,6 +1,4 @@
 #!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -38,6 +36,7 @@
 from cros.factory.device import device_utils
 from cros.factory.test import factory
 from cros.factory.test.fixture import bft_fixture
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
@@ -132,21 +131,23 @@
     html = ['<div class="test-vcenter-outer"><div class="test-vcenter-inner">']
 
     if not self.args.disable_input_on_fail or all_pass:
-      html = html + ['<a onclick="onclick:window.test.pass()" href="#">',
-                     test_ui.MakeLabel('Click or press SPACE to continue',
-                                       u'点击或按空白键继续'),
-                     '</a><br>']
+      html = html + [
+          '<a onclick="onclick:window.test.pass()" href="#">',
+          i18n_test_ui.MakeI18nLabel('Click or press SPACE to continue'),
+          '</a><br>'
+      ]
     else:
-      html = html + [test_ui.MakeLabel(
-          'Unable to proceed, since some previous tests have not passed.',
-          u'之前所有的测试必须通过才能通过此项目')]
+      html = html + [
+          i18n_test_ui.MakeI18nLabel(
+              'Unable to proceed, since some previous tests have not passed.')
+      ]
 
     html = html + [
-        test_ui.MakeLabel('Test Status for %s:' % test.parent.path,
-                          u'%s 测试结果列表:' % test.parent.path),
-        '<div class="test-status-%s" style="font-size: 300%%">%s</div>' % (
-            overall_status, test_ui.MakeStatusLabel(overall_status)),
-        '<table>'] + table + ['</table>'] + ['</div></div>']
+        i18n_test_ui.MakeI18nLabel(
+            'Test Status for {test}:', test=test.parent.path),
+        '<div class="test-status-%s" style="font-size: 300%%">%s</div>' %
+        (overall_status, test_ui.MakeStatusLabel(overall_status)), '<table>'
+    ] + table + ['</table>'] + ['</div></div>']
 
     if self.args.accessibility and not all_pass:
       html = ['<div class="test-vcenter-accessibility">'] + html + ['</div>']
diff --git a/py/test/pytests/suspend_resume.py b/py/test/pytests/suspend_resume.py
index fa7642c..64e1e43 100644
--- a/py/test/pytests/suspend_resume.py
+++ b/py/test/pytests/suspend_resume.py
@@ -1,4 +1,3 @@
-# -*- mode: python; coding: utf-8 -*-
 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -27,6 +26,7 @@
 import factory_common  # pylint: disable=unused-import
 from cros.factory.test import event_log
 from cros.factory.test import factory
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
@@ -35,8 +35,8 @@
 from cros.factory.utils import process_utils
 from cros.factory.utils import sync_utils
 
-_TEST_TITLE = test_ui.MakeLabel('Suspend/Resume Test', zh=u'暂停/恢复测试')
-_MSG_CYCLE = test_ui.MakeLabel('Suspend/Resume:', zh=u'暂停/恢复:')
+_TEST_TITLE = i18n_test_ui.MakeI18nLabel('Suspend/Resume Test')
+_MSG_CYCLE = i18n_test_ui.MakeI18nLabel('Suspend/Resume:')
 _ID_CYCLES = 'sr_cycles'
 _ID_RUN = 'sr_run'
 _TEST_BODY = ('<font size="20">%s <div id="%s"></div> of \n'
diff --git a/py/test/pytests/sync_shopfloor.py b/py/test/pytests/sync_shopfloor.py
index 8fc6345..b6f7576 100644
--- a/py/test/pytests/sync_shopfloor.py
+++ b/py/test/pytests/sync_shopfloor.py
@@ -1,6 +1,4 @@
 #!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -12,6 +10,7 @@
 import factory_common  # pylint: disable=unused-import
 from cros.factory.goofy import updater
 from cros.factory.test import factory
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import shopfloor
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
@@ -67,9 +66,8 @@
         return has_update
 
       while True:
-        template.SetState(test_ui.MakeLabel(
-            'Contacting shopfloor server...',
-            '正在与shopfloor server连线...'))
+        template.SetState(
+            i18n_test_ui.MakeI18nLabel('Contacting shopfloor server...'))
         shopfloor_url = shopfloor.get_server_url()
         if shopfloor_url:
           template.SetState('<br>' + shopfloor_url, append=True)
@@ -90,12 +88,9 @@
             return
           else:
             # Display message and require update.
-            template.SetState(test_ui.MakeLabel(
-                'A software update is available. '
-                'Press SPACE to update.',
-
-                u'有可用的更新。'
-                u'按空白键更新。'))
+            template.SetState(
+                i18n_test_ui.MakeI18nLabel('A software update is available. '
+                                           'Press SPACE to update.'))
 
             # Note that updateFactory() will kill this test.
             ui.BindKeyJS(test_ui.SPACE_KEY, 'window.test.updateFactory()')
@@ -107,21 +102,17 @@
           logging.error('Unable to sync with shopfloor server: %s',
                         exception_string)
 
+        msg = lambda time_left: i18n_test_ui.MakeI18nLabel(
+            'Unable to contact shopfloor server.'
+            ' Will try again in {time_left} seconds.', time_left=time_left)
         template.SetState(
-            test_ui.MakeLabel(
-                ('Unable to contact shopfloor server. '
-                 'Will try again in '),
-                '无法连线到 shopfloor server。') +
-            ('<span id="retry">%d</span>' % retry_secs) +
-            test_ui.MakeLabel(
-                ' seconds.',
-                '秒后自动重试。') +
-            '<div class=sync-detail>' +
-            test_ui.Escape(exception_string) + '</div>')
+            '<span id="retry">' + msg(retry_secs) + '</span>'
+            + '<div class=sync-detail>'
+            + test_ui.Escape(exception_string) + '</div>')
 
         for i in xrange(retry_secs):
           time.sleep(1)
-          ui.SetHTML(str(retry_secs - i - 1), id='retry')
+          ui.SetHTML(msg(retry_secs - i - 1), id='retry')
 
         retry_secs = min(2 * retry_secs, self.args.retry_secs)
 
diff --git a/py/test/pytests/sysfs_battery.py b/py/test/pytests/sysfs_battery.py
index 240fcc2..7725123 100644
--- a/py/test/pytests/sysfs_battery.py
+++ b/py/test/pytests/sysfs_battery.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -15,11 +13,12 @@
 import factory_common  # pylint: disable=unused-import
 from cros.factory.device import device_utils
 from cros.factory.test import event_log
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 
-_TEST_TITLE = test_ui.MakeLabel('Battery Self-diagnosis', u'电池自我诊断')
+_TEST_TITLE = i18n_test_ui.MakeI18nLabel('Battery Self-diagnosis')
 _CSS = '#state {text-align:left;}'
 
 
diff --git a/py/test/pytests/tablet_mode_ui.py b/py/test/pytests/tablet_mode_ui.py
index 1a5b774..cee0810 100644
--- a/py/test/pytests/tablet_mode_ui.py
+++ b/py/test/pytests/tablet_mode_ui.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright 2015 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -11,24 +9,20 @@
 
 import factory_common  # pylint: disable=unused-import
 
-from cros.factory.test import test_ui
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test.ui_templates import OneSection
 
 
 _FLASH_STATUS_TIME = 1
 
-_MSG_PROMPT_FLIP_TABLET = test_ui.MakeLabel(
-    'Flip the lid into tablet mode', u'把上盖掀开一圈直到贴合下盖')
-_MSG_PROMPT_FLIP_NOTEBOOK = test_ui.MakeLabel(
-    'Open the lid back to notebook mode', u'把上盖掀开直到正常笔电模式')
-_MSG_CONFIRM_TABLET_MODE = test_ui.MakeLabel(
-    'Confirm tablet mode', u'确认平板模式')
-_MSG_CONFIRM_NOTEBOOK_MODE = test_ui.MakeLabel(
-    'Confirm notebook mode', u'确认笔电模式')
-_MSG_STATUS_SUCCESS = test_ui.MakeLabel(
-    'Success!', u'成功!')
-_MSG_STATUS_FAILURE = test_ui.MakeLabel(
-    'Failure', u'失败')
+_MSG_PROMPT_FLIP_TABLET = i18n_test_ui.MakeI18nLabel(
+    'Flip the lid into tablet mode')
+_MSG_PROMPT_FLIP_NOTEBOOK = i18n_test_ui.MakeI18nLabel(
+    'Open the lid back to notebook mode')
+_MSG_CONFIRM_TABLET_MODE = i18n_test_ui.MakeI18nLabel('Confirm tablet mode')
+_MSG_CONFIRM_NOTEBOOK_MODE = i18n_test_ui.MakeI18nLabel('Confirm notebook mode')
+_MSG_STATUS_SUCCESS = i18n_test_ui.MakeI18nLabel('Success!')
+_MSG_STATUS_FAILURE = i18n_test_ui.MakeI18nLabel('Failure')
 
 _ID_PROMPT = 'lid-test-prompt'
 _ID_CONFIRM_BUTTON = 'confirm-button'
diff --git a/py/test/pytests/tablet_rotation.py b/py/test/pytests/tablet_rotation.py
index ec72e63..2fc9849 100644
--- a/py/test/pytests/tablet_rotation.py
+++ b/py/test/pytests/tablet_rotation.py
@@ -61,6 +61,7 @@
 from cros.factory.device import device_utils
 from cros.factory.test import countdown_timer
 from cros.factory.test import factory
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test.pytests import tablet_mode_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
@@ -73,10 +74,9 @@
 _TEST_DEGREES = [90, 180, 270, 0]
 _POLL_ROTATION_INTERVAL = 0.1
 
-_MSG_PROMPT_ROTATE_TABLET = test_ui.MakeLabel(
+_MSG_PROMPT_ROTATE_TABLET = i18n_test_ui.MakeI18nLabel(
     'Rotate the tablet to correctly align the picture, holding it at an '
-    'upright 90-degree angle.',
-    u'竖立平板电脑使其垂直于桌面,并开始旋转到对齐图片。')
+    'upright 90-degree angle.')
 
 _ID_COUNTDOWN_TIMER = 'countdown-timer'
 _ID_PROMPT = 'prompt'
diff --git a/py/test/pytests/touchpad.py b/py/test/pytests/touchpad.py
index 17ef708..19722dd 100644
--- a/py/test/pytests/touchpad.py
+++ b/py/test/pytests/touchpad.py
@@ -20,6 +20,7 @@
 import factory_common  # pylint: disable=unused-import
 from cros.factory.test import countdown_timer
 from cros.factory.test import factory
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.test.utils import evdev_utils
@@ -34,9 +35,8 @@
 # here to make the layout consistent.
 _HTML_TIMER = '<div id="%s">&nbsp;</div>' % _ID_COUNTDOWN_TIMER
 
-_HTML_PROMPT = test_ui.MakeLabel(
+_HTML_PROMPT = i18n_test_ui.MakeI18nLabelWithClass(
     'Please take off your fingers and then press SPACE to start testing...',
-    u'请先将手指远离触控版後按 "空白键" 开始测试...',
     'touchpad-test-prompt') + _HTML_TIMER
 
 # The layout contains one div for touchpad touch and scroll,
diff --git a/py/test/pytests/touchpad_hover.py b/py/test/pytests/touchpad_hover.py
index 1fc5c98..32c50ee 100644
--- a/py/test/pytests/touchpad_hover.py
+++ b/py/test/pytests/touchpad_hover.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 # Copyright 2016 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -15,6 +14,7 @@
 from cros.factory.external import evdev
 from cros.factory.test.args import Arg
 from cros.factory.test import countdown_timer
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.test.utils import evdev_utils
@@ -22,18 +22,12 @@
 from cros.factory.utils import type_utils
 
 
-_MSG_CALIBRATION = test_ui.MakeLabel(
-    'Calibrating touchpad...',
-    u'触控面板校正中...')
-_MSG_PUT_IN = test_ui.MakeLabel(
-    'Please put the hover-tool into the holder.',
-    u'请将悬停测试用具放入支架中')
-_MSG_PULL_OUT = test_ui.MakeLabel(
-    'Please pull out the hover-tool from the holder.',
-    u'请将悬停测试用具从支架移除')
-_MSG_FP_CHECK = test_ui.MakeLabel(
-    'Checking for false positive...',
-    u'进行假阳性检查...')
+_MSG_CALIBRATION = i18n_test_ui.MakeI18nLabel('Calibrating touchpad...')
+_MSG_PUT_IN = i18n_test_ui.MakeI18nLabel(
+    'Please put the hover-tool into the holder.')
+_MSG_PULL_OUT = i18n_test_ui.MakeI18nLabel(
+    'Please pull out the hover-tool from the holder.')
+_MSG_FP_CHECK = i18n_test_ui.MakeI18nLabel('Checking for false positive...')
 
 _ID_PROMPT = 'touchpad-hover-test-prompt'
 _ID_TIMER = 'touchpad-hover-test-timer'
diff --git a/py/test/pytests/touchscreen_uniformity.py b/py/test/pytests/touchscreen_uniformity.py
index 57705d6..8bba3d3 100644
--- a/py/test/pytests/touchscreen_uniformity.py
+++ b/py/test/pytests/touchscreen_uniformity.py
@@ -36,24 +36,25 @@
 from cros.factory.external import numpy
 from cros.factory.test import event_log
 from cros.factory.test import factory_task
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 
 
-_LABEL_CALIBRATING_TOUCHSCREEN = test_ui.MakeLabel('Calibrating Touchscreen',
-                                                   u'触屏校正中', 'test-info')
-_LABEL_NOT_FOUND = test_ui.MakeLabel('ERROR: Touchscreen Not Found',
-                                     u'没有找到触屏', 'test-fail')
-_LABEL_TESTING_REFERENCES = test_ui.MakeLabel('Testing References',
-                                              u'参考值测试中', 'test-info')
-_LABEL_TESTING_DELTAS = test_ui.MakeLabel('Testing Deltas',
-                                          u'差量测试中', 'test-info')
-_LABEL_PASS = test_ui.MakeLabel('PASS', u'成功', 'test-pass')
-_LABEL_FAIL = test_ui.MakeLabel('FAIL', u'失败', 'test-fail')
+_LABEL_CALIBRATING_TOUCHSCREEN = i18n_test_ui.MakeI18nLabelWithClass(
+    'Calibrating Touchscreen', 'test-info')
+_LABEL_NOT_FOUND = i18n_test_ui.MakeI18nLabelWithClass(
+    'ERROR: Touchscreen Not Found', 'test-fail')
+_LABEL_TESTING_REFERENCES = i18n_test_ui.MakeI18nLabelWithClass(
+    'Testing References', 'test-info')
+_LABEL_TESTING_DELTAS = i18n_test_ui.MakeI18nLabelWithClass(
+    'Testing Deltas', 'test-info')
+_LABEL_PASS = i18n_test_ui.MakeI18nLabelWithClass('PASS', 'test-pass')
+_LABEL_FAIL = i18n_test_ui.MakeI18nLabelWithClass('FAIL', 'test-fail')
 _MESSAGE_DELAY_SECS = 1
 
-_BR = '<br/>'
+_BR = '<br>'
 
 _CSS = """
   .test-info {font-size: 2em;}
diff --git a/py/test/pytests/tpm_diagnosis.py b/py/test/pytests/tpm_diagnosis.py
index a7f7fe2..a582aee 100644
--- a/py/test/pytests/tpm_diagnosis.py
+++ b/py/test/pytests/tpm_diagnosis.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -13,12 +11,13 @@
 import unittest
 
 import factory_common  # pylint: disable=unused-import
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 from cros.factory.utils import process_utils
 
-_TEST_TITLE = test_ui.MakeLabel('TPM Self-diagnosis', u'TPM 自我诊断')
+_TEST_TITLE = i18n_test_ui.MakeI18nLabel('TPM Self-diagnosis')
 _CSS = '#state {text-align:left;}'
 
 
diff --git a/py/test/pytests/update_firmware.py b/py/test/pytests/update_firmware.py
index 56e36fc..a7966ee 100644
--- a/py/test/pytests/update_firmware.py
+++ b/py/test/pytests/update_firmware.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -16,13 +14,14 @@
 from cros.factory.device import device_utils
 from cros.factory.test.env import paths
 from cros.factory.test import event
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import shopfloor
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 from cros.factory.utils import process_utils
 
-_TEST_TITLE = test_ui.MakeLabel('Update Firmware', u'更新韧体')
+_TEST_TITLE = i18n_test_ui.MakeI18nLabel('Update Firmware')
 _CSS = '#state {text-align:left;}'
 
 
diff --git a/py/test/pytests/update_kernel.py b/py/test/pytests/update_kernel.py
index b2c27fc..690b623 100644
--- a/py/test/pytests/update_kernel.py
+++ b/py/test/pytests/update_kernel.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright 2015 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -12,12 +10,13 @@
 import unittest
 
 import factory_common  # pylint: disable=unused-import
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 from cros.factory.utils import process_utils
 
-_TEST_TITLE = test_ui.MakeLabel('Update Kernel', u'更新 Kernel')
+_TEST_TITLE = i18n_test_ui.MakeI18nLabel('Update Kernel')
 _CSS = '#state {text-align:left;}'
 
 
diff --git a/py/test/pytests/usb.py b/py/test/pytests/usb.py
index ffe3818..b9dcd773 100644
--- a/py/test/pytests/usb.py
+++ b/py/test/pytests/usb.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -12,14 +10,15 @@
 # ports specified.
 
 
-import unittest
 import logging
 import os
 import pyudev
 import threading
+import unittest
 
 import factory_common  # pylint: disable=unused-import
 from cros.factory.test import factory
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
@@ -28,10 +27,9 @@
 _UDEV_ACTION_INSERT = 'add'
 _UDEV_ACTION_REMOVE = 'remove'
 
-_MSG_PROMPT_FMT = lambda t: test_ui.MakeLabel(
-    'Plug device into each USB port, %d to go...<br>' % t,
-    zh='在每个 USB 端口插入装置, 还有 %d 个待测试...<br>' % t,
-    css_class='usb-test-info')
+_MSG_PROMPT_FMT = lambda num_usb_ports: i18n_test_ui.MakeI18nLabelWithClass(
+    'Plug device into each USB port, {num_usb_ports} to go...<br>',
+    'usb-test-info', num_usb_ports=num_usb_ports)
 
 # The layout contains one div for usb test
 _ID_CONTAINER = 'usb-test-container'
diff --git a/py/test/pytests/verify_components.py b/py/test/pytests/verify_components.py
index f89ec87..dd901a7 100644
--- a/py/test/pytests/verify_components.py
+++ b/py/test/pytests/verify_components.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -17,6 +15,7 @@
 from cros.factory.device import device_utils
 from cros.factory.test import event_log
 from cros.factory.test import factory
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test.rules import phase
 from cros.factory.test import shopfloor
 from cros.factory.test import test_ui
@@ -24,10 +23,9 @@
 from cros.factory.test.utils import deploy_utils
 from cros.factory.utils.arg_utils import Arg
 
-_TEST_TITLE = test_ui.MakeLabel('Components Verification Test',
-                                u'元件验证测试')
-_MESSAGE_CHECKING_COMPONENTS = test_ui.MakeLabel(
-    'Checking components...', u'元件验证中...', 'progress-message')
+_TEST_TITLE = i18n_test_ui.MakeI18nLabel('Components Verification Test')
+_MESSAGE_CHECKING_COMPONENTS = i18n_test_ui.MakeI18nLabelWithClass(
+    'Checking components...', 'progress-message')
 
 
 class VerifyComponentsTest(unittest.TestCase):
diff --git a/py/test/pytests/verify_components_unittest.py b/py/test/pytests/verify_components_unittest.py
index b5ca39f..6b8cc16 100755
--- a/py/test/pytests/verify_components_unittest.py
+++ b/py/test/pytests/verify_components_unittest.py
@@ -14,10 +14,10 @@
 
 import factory_common  # pylint: disable=unused-import
 from cros.factory.test import event_log
-from cros.factory.test import shopfloor
-from cros.factory.test import test_ui
 from cros.factory.test.factory import FactoryTestFailure
 from cros.factory.test.pytests import verify_components
+from cros.factory.test import shopfloor
+from cros.factory.test import test_ui
 from cros.factory.test.ui_templates import OneSection
 from cros.factory.test.utils.deploy_utils import FactoryPythonArchive
 
@@ -73,7 +73,7 @@
             u'error': None}]}
 
     self._mock_test._ui.Run(blocking=False)
-    self._mock_test.template.SetState(mox.IsA(unicode))
+    self._mock_test.template.SetState(mox.IsA(basestring))
     self._mock_test.factory_par.CheckOutput(command).AndReturn(
         json.dumps(probed))
 
@@ -112,7 +112,7 @@
             u'error': u'Fake error'}]}
 
     self._mock_test._ui.Run(blocking=False)
-    self._mock_test.template.SetState(mox.IsA(unicode))
+    self._mock_test.template.SetState(mox.IsA(basestring))
     self._mock_test.factory_par.CheckOutput(command).AndReturn(
         json.dumps(probed))
 
@@ -137,7 +137,7 @@
                '--phase', self.fake_phase]
 
     self._mock_test._ui.Run(blocking=False)
-    self._mock_test.template.SetState(mox.IsA(unicode))
+    self._mock_test.template.SetState(mox.IsA(basestring))
     self._mock_test.factory_par.CheckOutput(command).AndRaise(
         subprocess.CalledProcessError(1, 'Fake command'))
 
diff --git a/py/test/pytests/verify_value.py b/py/test/pytests/verify_value.py
index f07ebb5..0c8efb8 100644
--- a/py/test/pytests/verify_value.py
+++ b/py/test/pytests/verify_value.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright 2016 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -13,23 +11,28 @@
 import factory_common  # pylint: disable=unused-import
 from cros.factory.device import device_utils
 from cros.factory.test import factory
+from cros.factory.test import i18n
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 
 
-Item = namedtuple('CheckItem', 'name_en name_zh command expected_value')
+Item = namedtuple('CheckItem', 'name command expected_value')
 
 
 class VerifyValueTest(unittest.TestCase):
   ARGS = [
       Arg('items', list,
           'A list of tuples, each representing an item to check. Each tuple\n'
-          'is of the format:\n'
+          'is one of the formats:\n'
+          '\n'
+          '  (name, command/func_name, expected_value)\n'
           '\n'
           '  (name_en, name_zh, command/func_name, expected_value)\n'
           '\n'
           'The fields are:\n'
+          '    - name: name of the check, would be passed to i18n.Translated.\n'
           '    - name_en: (str or unicode) name of the check in English.\n'
           '    - name_zh: (str or unicode) name of the check in Chinese.\n'
           '    - command/func_name: (str or list) Can be one of the following:\n'
@@ -56,8 +59,12 @@
 
   def runTest(self):
     for item in self.args.items:
-      item = Item._make(item)
-      name = test_ui.MakeLabel(item.name_en, item.name_zh)
+      if len(item) == 4:
+        # TODO(pihsun): This is to maintain backward compatibility. Should be
+        #               removed after test lists are migrated to new format.
+        item = ({'en-US': item[0], 'zh-CN': item[1]}, item[2], item[3])
+      item = Item(i18n.Translated(item[0], translate=False), item[1], item[2])
+      name = i18n_test_ui.MakeI18nLabel(item.name)
       self._template.SetState(name)
       command = item.command
 
@@ -87,4 +94,4 @@
           break
 
       if not match:
-        self.fail('%s is not in %s' % (value_str, str(item.expected_value)))
+        self.fail('%s is not in %s' % (value_str, item.expected_value))
diff --git a/py/test/pytests/vpd.py b/py/test/pytests/vpd.py
index 0cd590b..4733e49 100644
--- a/py/test/pytests/vpd.py
+++ b/py/test/pytests/vpd.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -34,6 +32,9 @@
 from cros.factory.device import device_utils
 from cros.factory.test import factory
 from cros.factory.test import factory_task
+from cros.factory.test import i18n
+from cros.factory.test.i18n import _
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test.l10n import regions
 from cros.factory.test.rules import branding
 from cros.factory.test.rules import registration_codes
@@ -44,37 +45,31 @@
 from cros.factory.utils.arg_utils import Arg
 from cros.factory.utils import type_utils
 
-_MSG_FETCH_FROM_SHOP_FLOOR = test_ui.MakeLabel(
-    'Fetching VPD from shop floor server...',
-    u'从 Shop Floor 服务器抓取 VPD 中...',
-    'vpd-info')
-_MSG_WRITING = test_ui.MakeLabel(
-    'Writing VPD:</br>',
-    u'写入 VPD:</br>',
-    'vpd-info')
-_MSG_SELECT_REGION = test_ui.MakeLabel(
-    'Select region:</br>', u'选择区域代码:</br>', 'vpd-info')
-_MSG_HOW_TO_SELECT = test_ui.MakeLabel(
-    '</br>Select with ENTER', u'</br>按 ENTER 选择', 'vpd-info')
+_MSG_FETCH_FROM_SHOP_FLOOR = i18n_test_ui.MakeI18nLabelWithClass(
+    'Fetching VPD from shop floor server...', 'vpd-info')
+_MSG_WRITING = i18n_test_ui.MakeI18nLabelWithClass(
+    'Writing VPD:<br>', 'vpd-info')
+_MSG_SELECT_REGION = i18n_test_ui.MakeI18nLabelWithClass(
+    'Select region:<br>', 'vpd-info')
+_MSG_HOW_TO_SELECT = i18n_test_ui.MakeI18nLabelWithClass(
+    '<br>Select with ENTER', 'vpd-info')
+_MSG_MANUAL_INPUT_PROMPT = lambda vpd_label: (
+    i18n_test_ui.MakeI18nLabelWithClass(
+        'Enter {vpd_label}: ', 'vpd-info', vpd_label=vpd_label))
+_MSG_MANUAL_SELECT_PROMPT = lambda vpd_label: (
+    i18n_test_ui.MakeI18nLabelWithClass(
+        'Select {vpd_label}: <br>', 'vpd-info', vpd_label=vpd_label))
 # The "ESC" is available primarily for RMA and testing process, when operator
 # does not want to change existing serial number.
-_MSG_MANUAL_INPUT_PROMPT = lambda en, zh: test_ui.MakeLabel(
-    'Enter %s: ' % en, u'输入%s: ' % zh, 'vpd-info')
-_MSG_MANUAL_SELECT_PROMPT = lambda en, zh: test_ui.MakeLabel(
-    'Select %s: </br>' % en, u'选择%s: </br>' % zh, 'vpd-info')
-_MSG_ESC_TO_SKIP = lambda en, zh: test_ui.MakeLabel(
-    '</br>(ESC to re-use current machine %s)' % en,
-    u'</br>(ESC 使用目前已写入机器的%s)' % zh,
-    'vpd-info')
+_MSG_ESC_TO_SKIP = lambda vpd_label: i18n_test_ui.MakeI18nLabelWithClass(
+    '<br>(ESC to re-use current machine {vpd_label})',
+    'vpd-info', vpd_label=vpd_label)
 
-_ERR_NO_VALID_VPD = lambda en, zh: test_ui.MakeLabel(
-    'Found no valid %s on machine.' % en,
-    u'机器上并无合法的%s' % zh,
-    'vpd-info test-error')
-_ERR_INPUT_INVALID = lambda en, zh: test_ui.MakeLabel(
-    'Invalid %s value.' % en,
-    u'输入的%s不合法' % zh,
-    'vpd-info test-error')
+_ERR_NO_VALID_VPD = lambda vpd_label: i18n_test_ui.MakeI18nLabelWithClass(
+    'Found no valid {vpd_label} on machine.',
+    'vpd-info test-error', vpd_label=vpd_label)
+_ERR_INPUT_INVALID = lambda vpd_label: i18n_test_ui.MakeI18nLabelWithClass(
+    'Invalid {vpd_label} value.', 'vpd-info test-error', vpd_label=vpd_label)
 
 _DEFAULT_VPD_TEST_CSS = '.vpd-info {font-size: 2em;}'
 
@@ -131,7 +126,7 @@
 
     self.test.template.SetState(_MSG_WRITING)
     self.test.template.SetState('<div class="vpd-info">%s</div>' % (
-        '</br>'.join(vpd_list)), append=True)
+        '<br>'.join(vpd_list)), append=True)
 
     for vpd_type in self.test.vpd:
       partition = self.test.dut.vpd.GetPartition(vpd_type)
@@ -193,19 +188,14 @@
 class VPDInfo(object):
   """A class for checking all the manual input VPD fields."""
 
-  def __init__(self, region, key, label_en, label_zh, value_check):
+  def __init__(self, region, key, label, value_check):
     if region not in ['ro', 'rw']:
-      raise ValueError('VPD region must be either \'ro\' or \'rw\'.')
+      raise ValueError("VPD region must be either 'ro' or 'rw'.")
     self.region = region
     if not isinstance(key, str):
       raise TypeError('VPD id must be a string.')
     self.key = key
-    if not isinstance(label_en, (str, unicode)):
-      raise TypeError('VPD English label must be a string or unicode string.')
-    self.label_en = label_en
-    if not isinstance(label_zh, (str, unicode)):
-      raise TypeError('VPD Chinese label must be a string or unicode string.')
-    self.label_zh = label_zh
+    self.label = label
     if not isinstance(value_check, (list, str, type(None))):
       raise TypeError('VPD possible values must be a list of strings, '
                       'a regexp string, no None.')
@@ -252,8 +242,8 @@
     if vpd_value:
       if (isinstance(self.vpd_info.value_check, _REGEX_TYPE)) and (
           not self.vpd_info.value_check.match(vpd_value)):
-        self.test.ui.SetHTML(_ERR_INPUT_INVALID(
-            self.vpd_info.label_en, self.vpd_info.label_zh), id='errormsg')
+        self.test.ui.SetHTML(_ERR_INPUT_INVALID(self.vpd_info.label),
+                             id='errormsg')
         self.test.ui.SetSelected(self.vpd_info.key)
         return
       self.OnComplete(vpd_value)
@@ -262,8 +252,8 @@
     vpd_value = self.test.dut.vpd.GetPartition(
         self.vpd_info.region).get(self.vpd_info.key).strip()
     if not vpd_value:
-      self.test.ui.SetHTML(_ERR_NO_VALID_VPD(
-          self.vpd_info.label_en, self.vpd_info.label_zh), id='errormsg')
+      self.test.ui.SetHTML(_ERR_NO_VALID_VPD(self.vpd_info.label),
+                           id='errormsg')
     else:
       self.OnComplete(None)
 
@@ -279,8 +269,7 @@
 
   def RenderSelectBox(self):
     vpd_event_subtype = _EVENT_SUBTYPE_VPD_PREFIX + self.vpd_info.key
-    self.test.template.SetState(_MSG_MANUAL_SELECT_PROMPT(
-        self.vpd_info.label_en, self.vpd_info.label_zh))
+    self.test.template.SetState(_MSG_MANUAL_SELECT_PROMPT(self.vpd_info.label))
     select_box = ui_templates.SelectBox(self.vpd_info.key, _SELECTION_PER_PAGE,
                                         _SELECT_BOX_STYLE)
     for index, value in enumerate(self.vpd_info.value_check):
@@ -295,11 +284,9 @@
 
   def RenderInputBox(self):
     vpd_event_subtype = _EVENT_SUBTYPE_VPD_PREFIX + self.vpd_info.key
-    self.test.template.SetState(_MSG_MANUAL_INPUT_PROMPT(
-        self.vpd_info.label_en, self.vpd_info.label_zh))
+    self.test.template.SetState(_MSG_MANUAL_INPUT_PROMPT(self.vpd_info.label))
     self._AppendState(_HTML_MANUAL_INPUT(self.vpd_info.key))
-    self._AppendState(_MSG_ESC_TO_SKIP(self.vpd_info.label_en,
-                                       self.vpd_info.label_zh))
+    self._AppendState(_MSG_ESC_TO_SKIP(self.vpd_info.label))
     self.test.ui.BindKeyJS(test_ui.ENTER_KEY, _JS_MANUAL_INPUT(
         self.vpd_info.key, vpd_event_subtype))
     self.test.ui.AddEventHandler(vpd_event_subtype, self.OnEnterPressed)
@@ -386,7 +373,8 @@
     value = self.desc_value_dict[desc]
     # Check the format.
     if not self.regexp.match(value):
-      self.test.template.SetState(_ERR_INPUT_INVALID(self.key, self.key))
+      self.test.template.SetState(
+          _ERR_INPUT_INVALID(i18n.NoTranslation(self.key)))
       self.Fail('Bad format for %s %r (expected it to match regexp %r)' % (
           self.key, value, self.regexp.pattern))
     else:
@@ -395,8 +383,8 @@
 
   def RenderPage(self):
     vpd_event_subtype = _EVENT_SUBTYPE_VPD_PREFIX + self.key
-    self.test.template.SetState(_MSG_MANUAL_SELECT_PROMPT(
-        self.key, self.key))
+    self.test.template.SetState(
+        _MSG_MANUAL_SELECT_PROMPT(i18n.NoTranslation(self.key)))
     select_box = ui_templates.SelectBox(
         self.key, _SELECTION_PER_PAGE, _SELECT_BOX_STYLE)
     for index, description in enumerate(self.branding_list):
@@ -450,14 +438,15 @@
           'value from key should be added to the ro or rw VPD.  This option '
           'only applies if use_shopfloor_device_data is True.', default=[]),
       Arg('manual_input_fields', list,
-          'A list of tuples (vpd_region, key, en_display_name, '
-          'zh_display_name, VALUE_CHECK) indicating the VPD fields that need '
-          'to be manually entered.\nVALUE_CHECK can be a list of strings, a '
-          'regexp string, or None. If VALUE_CHECK is None or a regexp string '
-          'then a text input box will show up to let user input value. The '
-          'entered value will be validated if VALUE_CHECK is a regexp string. '
-          'Otherwise a select box containing all the possible values will be '
-          'used to let user select a value from it.',
+          'A list of tuples (vpd_region, key, display_name, VALUE_CHECK) or '
+          '(vpd_region, key, en_display_name, zh_display_name, VALUE_CHECK) '
+          'indicating the VPD fields that need to be manually entered.\n'
+          'VALUE_CHECK can be a list of strings, a regexp string, or None. '
+          'If VALUE_CHECK is None or a regexp string then a text input box '
+          'will show up to let user input value. The entered value will be '
+          'validated if VALUE_CHECK is a regexp string. Otherwise a select box '
+          'containing all the possible values will be used to let user select '
+          'a value from it.',
           default=[], optional=True),
       Arg('rlz_brand_code', (str, dict),
           'RLZ brand code to write to RO VPD.  This may be any of:\n'
@@ -542,22 +531,28 @@
       self.assertIn(i[0], ['ro', 'rw'])
 
     if not (self.args.override_vpd and self.ui.InEngineeringMode()):
+      manual_input_fields = []
+      for v in self.args.manual_input_fields:
+        if len(v) == 5:
+          # TODO(pihsun): This is to maintain backward compatibility. Should be
+          #               removed after test lists are migrated to new format.
+          v = (v[0], v[1], {'en-US': v[2], 'zh-CN': v[3]}, v[4])
+        v = (v[0], v[1], i18n.Translated(v[2], translate=False), v[3])
+        manual_input_fields.append(v)
       if shopfloor.is_enabled():
         # Grab from ShopFloor, then input manual fields (if any).
         if self.args.use_shopfloor_device_data:
           self._ReadShopFloorDeviceData()
         else:
           self.tasks += [ShopFloorVPDTask(self)]
-        for v in self.args.manual_input_fields:
-          self.tasks += [ManualInputTask(
-              self, VPDInfo(v[0], v[1], v[2], v[3], v[4]))]
+        for v in manual_input_fields:
+          self.tasks += [ManualInputTask(self, VPDInfo(*v))]
       else:
         if self.VPDTasks.serial in self.args.task_list:
-          self.args.manual_input_fields.insert(
-              0, ('ro', 'serial_number', 'Serial Number', u'序号', None))
-        for v in self.args.manual_input_fields:
-          self.tasks += [ManualInputTask(
-              self, VPDInfo(v[0], v[1], v[2], v[3], v[4]))]
+          manual_input_fields.insert(
+              0, ('ro', 'serial_number', _('Serial Number'), None))
+        for v in manual_input_fields:
+          self.tasks += [ManualInputTask(self, VPDInfo(*v))]
         if self.VPDTasks.region in self.args.task_list:
           self.tasks += [SelectRegionTask(self)]
       if self.args.override_vpd_entries:
diff --git a/py/test/pytests/vpd_from_http.py b/py/test/pytests/vpd_from_http.py
index 235cfff..6a36d96 100644
--- a/py/test/pytests/vpd_from_http.py
+++ b/py/test/pytests/vpd_from_http.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -13,22 +11,22 @@
 
 import time
 import unittest
-import yaml
 import urllib
 import urllib2
 import urlparse
+import yaml
 
 import factory_common  # pylint: disable=unused-import
+from cros.factory.test.i18n import _
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import shopfloor
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 from cros.factory.utils import schema
 
-_MSG_VPD_INFO = test_ui.MakeLabel(
-    'Please scan the panel serial number and press ENTER.',
-    zh='请扫描面板序号後按下 ENTER',
-    css_class='vpd-info')
+_MSG_VPD_INFO = i18n_test_ui.MakeI18nLabelWithClass(
+    'Please scan the panel serial number and press ENTER.', 'vpd-info')
 
 _HTML_VPD = """
 <div id="vpd_title"></div>
@@ -97,16 +95,16 @@
         'http', '%s:%d' % (self.args.hostname, self.args.port),
         self.args.service_path, '', '', ''))
 
-  def SetStatus(self, eng_msg, zh_msg):
+  def SetStatus(self, msg):
     """Sets status on the UI."""
-    msg = test_ui.MakeLabel(eng_msg, zh_msg, css_class='vpd-info')
+    msg = i18n_test_ui.MakeI18nLabelWithClass(msg, 'vpd-info')
     self.ui.SetHTML(msg, id='scan-status')
 
   def HandleScanValue(self, event):
     """Handles scaned value."""
     scan_value = str(event.data).strip()
     if not scan_value:
-      self.SetStatus('The scanned value is empty.', '扫描编号是空的。')
+      self.SetStatus(_('The scanned value is empty.'))
       self.ui.CallJSFunction('setClear')
       return
 
@@ -127,12 +125,11 @@
       data: 'None' string or a yaml format dictionary
     """
     if data == 'None':
-      self.SetStatus('No VPD updated', '没有VPD需要更新')
+      self.SetStatus(_('No VPD updated'))
       time.sleep(1)
       return
     vpd_setting = yaml.load(data)
-    self.SetStatus('Writing to VPD. Please wait…',
-                   '正在写到 VPD,请稍等…')
+    self.SetStatus(_('Writing to VPD. Please wait...'))
     try:
       self.SCHEMA.Validate(vpd_setting)
     except schema.SchemaException as e:
diff --git a/py/test/pytests/vpd_unittest.py b/py/test/pytests/vpd_unittest.py
index 4a1a42d..123b357 100755
--- a/py/test/pytests/vpd_unittest.py
+++ b/py/test/pytests/vpd_unittest.py
@@ -109,8 +109,9 @@
     # Stub out self.test.template.SetState().
     self.test_case.template = self.mox.CreateMock(OneSection)
     self.mox.StubOutWithMock(self.test_case.template, 'SetState')
-    self.test_case.template.SetState(mox.IsA(unicode)).AndReturn(0)
-    self.test_case.template.SetState(mox.IsA(str), append=True).AndReturn(0)
+    self.test_case.template.SetState(mox.IsA(basestring)).AndReturn(0)
+    self.test_case.template.SetState(mox.IsA(basestring),
+                                     append=True).AndReturn(0)
     # Stub out BuildBoard().short_name. Actually this is not required for
     # legacy code, we just use 'x86-generic' to pass the unit test.
     src = os.path.join(os.environ['CROS_WORKON_SRCROOT'], 'src')
@@ -137,8 +138,9 @@
     # Stub out self.test.template.SetState().
     self.test_case.template = self.mox.CreateMock(OneSection)
     self.mox.StubOutWithMock(self.test_case.template, 'SetState')
-    self.test_case.template.SetState(mox.IsA(unicode)).AndReturn(0)
-    self.test_case.template.SetState(mox.IsA(str), append=True).AndReturn(0)
+    self.test_case.template.SetState(mox.IsA(basestring)).AndReturn(0)
+    self.test_case.template.SetState(mox.IsA(basestring),
+                                     append=True).AndReturn(0)
 
     # Stub out vpd.Update()
     self.vpd_ro.Update({}).AndReturn(0)
diff --git a/py/test/pytests/vswr/vswr.py b/py/test/pytests/vswr/vswr.py
index a051b05..7194864 100644
--- a/py/test/pytests/vswr/vswr.py
+++ b/py/test/pytests/vswr/vswr.py
@@ -47,6 +47,9 @@
 from cros.factory.test import event as test_event
 from cros.factory.test import event_log
 from cros.factory.test import factory
+from cros.factory.test import i18n
+from cros.factory.test.i18n import _
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import rf
 from cros.factory.test.rf import e5071c_scpi
 from cros.factory.test import shopfloor
@@ -520,17 +523,15 @@
       letter = random.choice(string.ascii_uppercase)
       factory.console.info('Press %s to continue', letter)
       # TODO(littlecvr): Should not construct HTML string here.
-      html_string_en = ''
-      html_string_ch = ''
+      html_string = ''
       for port in measurement_sequence:
         antenna_name = measurement_sequence[port]['name']
-        html_string_en += (
-            'Make sure the %s antennta is connected to port %s<br>' % (
-                antenna_name, port))
-        html_string_ch += u'连接 %s 天线至 port %s<br>' % (antenna_name, port)
-      html_string_en += 'Then press key "%s" to next stage.' % letter
-      html_string_ch += u'完成后按 %s 键' % letter
-      html_string = test_ui.MakeLabel(html_string_en, html_string_ch)
+        html_string = i18n.StringJoin(html_string, i18n.StringFormat(
+            _('Make sure the {name} antennta is connected to port {port}<br>'),
+            name=antenna_name, port=port))
+      html_string = i18n.StringJoin(html_string, i18n.StringFormat(
+          _('Then press key "{key}" to next stage.'), key=letter))
+      html_string = i18n_test_ui.MakeI18nLabel(html_string)
       self._ui.SetHTML(html_string, id='state-prepare-antennas')
       self._ShowMessageBlock('prepare-antennas')
       self._WaitForKey(letter)
diff --git a/py/test/pytests/webrtc_camera.py b/py/test/pytests/webrtc_camera.py
index b13d851..3378573 100644
--- a/py/test/pytests/webrtc_camera.py
+++ b/py/test/pytests/webrtc_camera.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -14,13 +12,14 @@
 import unittest
 
 import factory_common  # pylint: disable=unused-import
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 from cros.factory.utils import process_utils
 
-_MSG_TIME_REMAINING = lambda t: test_ui.MakeLabel(
-    'Time remaining: %d' % t, u'剩余时间:%d' % t, 'camera-test-info')
+_MSG_TIME_REMAINING = lambda time: i18n_test_ui.MakeI18nLabelWithClass(
+    'Time remaining: {time}', 'camera-test-info', time=time)
 _ID_IMAGE = 'camera-test-image'
 _ID_PROMPT1 = 'camera-test-prompt1'
 _ID_PROMPT2 = 'camera-test-prompt2'
@@ -40,14 +39,11 @@
     'id_prompt1': _ID_PROMPT1,
     'id_prompt2': _ID_PROMPT2,
     'id_timer': _ID_COUNTDOWN_TIMER,
-    'prompt1': test_ui.MakeLabel(
-        'Click "Allow" at the top of the screen.',
-        zh=u'点击上面的 "Allow" 按钮'),
-    'prompt2': test_ui.MakeLabel(
-        ('Click <a href="javascript:test.pass()">pass</a> or '
-         '<a href="javascript:test.fail()">fail</a>.'),
-        zh=(u'请点击: <a href="javascript:test.pass()">正常</a> 还是 '
-            u'<a href="javascript:test.fail()">不正常</a>')),
+    'prompt1': i18n_test_ui.MakeI18nLabel(
+        'Click "Allow" at the top of the screen.'),
+    'prompt2': i18n_test_ui.MakeI18nLabel(
+        'Click <a href="javascript:test.pass()">pass</a> or '
+        '<a href="javascript:test.fail()">fail</a>.'),
 }
 
 _JS_WEBRTC_CAMERA = """
diff --git a/py/test/pytests/wifi_rf.py b/py/test/pytests/wifi_rf.py
index 4430bca..13cae4b 100644
--- a/py/test/pytests/wifi_rf.py
+++ b/py/test/pytests/wifi_rf.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -26,34 +24,28 @@
 
 import factory_common  # pylint: disable=unused-import
 from cros.factory.test import factory
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 
-_TEST_TITLE = test_ui.MakeLabel('RMA Factory WiFi RF Test')
+_TEST_TITLE = i18n_test_ui.MakeI18nLabel('RMA Factory WiFi RF Test')
 
-TestRow = collections.namedtuple('TestRow', 'en_label zh_label freq antenna db')
+TestRow = collections.namedtuple('TestRow', 'freq antenna db')
 _SUBTESTS = []
-_SUBTESTS.append(TestRow(
-    '2.4GHz Antenna 1.', '2.4GHz 天线 1.', '2.4', '1', -65))
-_SUBTESTS.append(TestRow(
-    '2.4GHz Antenna 2.', '2.4GHz 天线 2.', '2.4', '2', -62))
-_SUBTESTS.append(TestRow(
-    '5.5GHz Antenna 1.', '5.5GHz 天线 1.', '5.5', '1', -68))
-_SUBTESTS.append(TestRow(
-    '5.5GHz Antenna 2.', '5.5GHz 天线 2.', '5.5', '2', -57))
+_SUBTESTS.append(TestRow('2.4', '1', -65))
+_SUBTESTS.append(TestRow('2.4', '2', -62))
+_SUBTESTS.append(TestRow('5.5', '1', -68))
+_SUBTESTS.append(TestRow('5.5', '2', -57))
 
 
-_MSG_INSTRUCTION = test_ui.MakeLabel(
-    'WiFi RF Chamber Testing.', u'WiFi RF 测试')
+_MSG_INSTRUCTION = i18n_test_ui.MakeI18nLabel('WiFi RF Chamber Testing.')
 
-_MSG_CHAMBER_REMOVE = test_ui.MakeLabel(
-    'Remove device from chamber. Press SPACE when re-attached to network.',
-    u'将装置从测试箱取出,重新连接网路后按下空白键')
+_MSG_CHAMBER_REMOVE = i18n_test_ui.MakeI18nLabel(
+    'Remove device from chamber. Press SPACE when re-attached to network.')
 
-_MSG_READY_CLOSE = test_ui.MakeLabel(
-    'Place device in WiFi chamber. When ready to close chamber, press SPACE.',
-    u'将设备放置在WiFi室。当您准备关闭室,按空白键。')
+_MSG_READY_CLOSE = i18n_test_ui.MakeI18nLabel(
+    'Place device in WiFi chamber. When ready to close chamber, press SPACE.')
 
 # Here's a command line that can be used to find the USB-serial dongle
 #_CMD_FINDTTY = '/usr/bin/find /sys/bus/usb/drivers/pl2303/2-1.2\:1.0/ '\
@@ -218,8 +210,8 @@
     """
     # Delay to let operator close RF Chamber door after hitting SPACE key.
     for i in range(5, 0, -1):
-      self._template.SetState(test_ui.MakeLabel(
-          'Countdown', '倒计时') + ': %d ' % i)
+      self._template.SetState(
+          i18n_test_ui.MakeI18nLabel('Countdown') + ': %d ' % i)
       time.sleep(1)
 
     # Have serial port initialization here because the USB-serial dongle
diff --git a/py/test/pytests/wifi_throughput.py b/py/test/pytests/wifi_throughput.py
index 9ea7830..ed7004c 100644
--- a/py/test/pytests/wifi_throughput.py
+++ b/py/test/pytests/wifi_throughput.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright 2014 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -70,27 +68,28 @@
 import logging
 import os
 import string  # pylint: disable=W0402
-import sys
 import subprocess
+import sys
 import threading
 import time
 import unittest
 
 import factory_common  # pylint: disable=unused-import
-from cros.factory.device import device_utils
 from cros.factory.device import CalledProcessError
+from cros.factory.device import device_utils
 from cros.factory.test import event_log
 from cros.factory.test import factory
+from cros.factory.test.fixture import arduino
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import leds
 from cros.factory.test import test_ui
 from cros.factory.test import testlog
-from cros.factory.test.fixture import arduino
 from cros.factory.test.ui_templates import OneSection
+from cros.factory.utils import arg_utils
+from cros.factory.utils.arg_utils import Arg
 from cros.factory.utils import net_utils
 from cros.factory.utils import sync_utils
 from cros.factory.utils import type_utils
-from cros.factory.utils import arg_utils
-from cros.factory.utils.arg_utils import Arg
 
 
 _WIFI_TIMEOUT_SECS = 20
@@ -99,14 +98,11 @@
 
 _DEFAULT_WIRELESS_TEST_CSS = '.wireless-info {font-size: 2em;}'
 
-_MSG_SPACE = test_ui.MakeLabel(
+_MSG_SPACE = i18n_test_ui.MakeI18nLabelWithClass(
     'Please wait for other DUTs to finish WiFiThroughput test, '
-    'and press spacebar to continue.',
-    u'请等其它的 DUT 完成测试後按空白键继续。',
-    'wireless-info')
-_MSG_RUNNING = test_ui.MakeLabel(
-    'Running, please wait...',
-    u'测试中,请稍後。', 'wireless-info')
+    'and press spacebar to continue.', 'wireless-info')
+_MSG_RUNNING = i18n_test_ui.MakeI18nLabelWithClass('Running, please wait...',
+                                                   'wireless-info')
 
 
 def _MbitsToBits(x):
diff --git a/py/test/pytests/wireless_antenna.py b/py/test/pytests/wireless_antenna.py
index 85d5381..a2ad6fa 100644
--- a/py/test/pytests/wireless_antenna.py
+++ b/py/test/pytests/wireless_antenna.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -28,6 +26,7 @@
 import factory_common  # pylint: disable=unused-import
 from cros.factory.test import event_log
 from cros.factory.test import factory
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
@@ -35,21 +34,20 @@
 
 _DEFAULT_WIRELESS_TEST_CSS = '.wireless-info {font-size: 2em;}'
 
-_MSG_SWITCHING_ANTENNA = lambda antenna: test_ui.MakeLabel(
-    'Switching to antenna %s: ' % antenna,
-    u'切换到天线 %s...' % antenna,
-    'wireless-info')
-_MSG_SCANNING = lambda device, freq: test_ui.MakeLabel(
-    'Scanning on device %s frequency %d...' % (device, freq),
-    u'在装置 %s 上扫描频率%d...' % (device, freq),
-    'wireless-info')
-_MSG_SCANNING_DONE = lambda device, freq: test_ui.MakeLabel(
-    'Done scanning on device %s frequency %d...' % (device, freq),
-    u'在装置 %s 上扫描频率%d 完成' % (device, freq),
-    'wireless-info')
-_MSG_SPACE = test_ui.MakeLabel(
-    'Press space to start scanning.',
-    u'请按空白键开始扫描。', 'wireless-info')
+_MSG_SWITCHING_ANTENNA = lambda antenna: i18n_test_ui.MakeI18nLabelWithClass(
+    'Switching to antenna {antenna}: ', 'wireless-info', antenna=antenna)
+_MSG_SCANNING = lambda device, freq: i18n_test_ui.MakeI18nLabelWithClass(
+    'Scanning on device {device} frequency {freq}...',
+    'wireless-info',
+    device=device,
+    freq=freq)
+_MSG_SCANNING_DONE = lambda device, freq: i18n_test_ui.MakeI18nLabelWithClass(
+    'Done scanning on device {device} frequency {freq}...',
+    'wireless-info',
+    device=device,
+    freq=freq)
+_MSG_SPACE = i18n_test_ui.MakeI18nLabelWithClass(
+    'Press space to start scanning.', 'wireless-info')
 
 _RE_FREQ = re.compile(r'^freq: ([\d]*?)$')
 _RE_SIGNAL = re.compile(r'^signal: ([-\d.]*?) dBm')
diff --git a/py/test/pytests/wireless_radiotap.py b/py/test/pytests/wireless_radiotap.py
index b10055e..6e2762e 100644
--- a/py/test/pytests/wireless_radiotap.py
+++ b/py/test/pytests/wireless_radiotap.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -33,6 +31,7 @@
 import factory_common  # pylint: disable=unused-import
 from cros.factory.test import event_log
 from cros.factory.test import factory
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
@@ -47,24 +46,18 @@
 
 _DEFAULT_WIRELESS_TEST_CSS = '.wireless-info {font-size: 2em;}'
 
-_MSG_SWITCHING_AP = lambda ap: test_ui.MakeLabel(
-    'Switching to AP %s: ' % ap,
-    u'切换到基地台 %s...' % ap,
-    'wireless-info')
-_MSG_SCANNING = lambda device, freq: test_ui.MakeLabel(
-    'Scanning on device %s frequency %d...' % (device, freq),
-    u'在装置 %s 上扫描频率%d...' % (device, freq),
-    'wireless-info')
-_MSG_SCANNING_DONE = lambda device, freq: test_ui.MakeLabel(
-    'Done scanning on device %s frequency %d...' % (device, freq),
-    u'在装置 %s 上扫描频率%d 完成' % (device, freq),
-    'wireless-info')
-_MSG_SPACE = test_ui.MakeLabel(
-    'Press space to start scanning.',
-    u'请按空白键开始扫描。', 'wireless-info')
-_MSG_PRECHECK = test_ui.MakeLabel(
-    'Checking frequencies...',
-    u'檢查頻率中...', 'wireless-info')
+_MSG_SWITCHING_AP = lambda ap: i18n_test_ui.MakeI18nLabelWithClass(
+    'Switching to AP {ap}: ', 'wireless-info', ap=ap)
+_MSG_SCANNING = lambda device, freq: i18n_test_ui.MakeI18nLabelWithClass(
+    'Scanning on device {device} frequency {freq}...',
+    'wireless-info', device=device, freq=freq)
+_MSG_SCANNING_DONE = lambda device, freq: i18n_test_ui.MakeI18nLabelWithClass(
+    'Done scanning on device {device} frequency {freq}...',
+    'wireless-info', device=device, freq=freq)
+_MSG_SPACE = i18n_test_ui.MakeI18nLabelWithClass(
+    'Press space to start scanning.', 'wireless-info')
+_MSG_PRECHECK = i18n_test_ui.MakeI18nLabelWithClass(
+    'Checking frequencies...', 'wireless-info')
 
 _RE_IWSCAN = re.compile(r'freq: (\d+).*SSID: (.+)$')
 _RE_WIPHY = re.compile(r'wiphy (\d+)')
diff --git a/py/test/pytests/write_device_data_to_vpd.py b/py/test/pytests/write_device_data_to_vpd.py
index 9a1b98b..ed9afd5 100644
--- a/py/test/pytests/write_device_data_to_vpd.py
+++ b/py/test/pytests/write_device_data_to_vpd.py
@@ -1,4 +1,3 @@
-# -*- mode: python; coding: utf-8 -*-
 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -14,14 +13,15 @@
 
 import factory_common  # pylint: disable=unused-import
 from cros.factory.device import device_utils
+from cros.factory.test.i18n import test_ui as i18n_test_ui
 from cros.factory.test import shopfloor
 from cros.factory.test import test_ui
 from cros.factory.test import ui_templates
 from cros.factory.utils.arg_utils import Arg
 
-_MSG_WRITING_VPD = lambda vpd_section: test_ui.MakeLabel(
-    'Writing device data to %s VPD...' % vpd_section.upper(),
-    '机器资料正在写入到 %s VPD...' % vpd_section.upper())
+_MSG_WRITING_VPD = lambda vpd_section: i18n_test_ui.MakeI18nLabel(
+    'Writing device data to {vpd_section} VPD...',
+    vpd_section=vpd_section.upper())
 
 
 class CallShopfloor(unittest.TestCase):