آموزش تست وب با TestComplete — از ضبط اسکریپت تا اجرای Cross-Browser
تست وب یکی از پرکاربردترین نوع تست اتوماتیک در تیمهای QA است. اکثر اپلیکیشنهای سازمانی امروز یک رابط وب دارند — چه پورتال داخلی باشد، چه فروشگاه آنلاین، چه سامانه حضور و غیاب. وقتی این رابط تغییر میکند، باید مطمئن شوید که چیزی نشکسته. این کار را به صورت دستی انجام دادن، در مقیاس، عملاً غیرممکن است.
نرم افزار TestComplete یکی از قدیمیترین و بالغترین ابزارهای تست UI وب است. برخلاف ابزارهایی که فقط با یک مرورگر یا یک فناوری کار میکنند، TestComplete از Chrome، Firefox، Edge و حتی IE پشتیبانی میکند — و هم با اسکریپتنویسی و هم بدون کد کار میکند.
در مقالههای قبلی این سری، تست API و تست موبایل با TestComplete را بررسی کردیم. این مقاله تکمیلکننده آن دو است: تست وب — از ضبط اولین تست تا اجرای cross-browser در pipeline CI/CD.
پیشنیازها
قبل از شروع، مطمئن شوید موارد زیر آماده هستند:
- TestComplete 15 (یا بالاتر) با ماژول Web نصب شده
- مرورگر Chrome یا Edge با TestComplete Extension فعال
- دسترسی به یک اپلیکیشن وب برای تست (در این مقاله از یک فرم ورود ساده استفاده میکنیم)
- آشنایی پایه با محیط TestComplete — اگر تازه شروع کردهاید، ابتدا صفحه اصلی TestComplete را مطالعه کنید
چرا تست وب با TestComplete؟
شاید بپرسید: «وقتی Selenium و Playwright وجود دارند، چرا TestComplete؟»
جواب بستگی دارد به تیم شما:
مزیت اصلی TestComplete نسبت به Selenium: رابط بصری و Object Repository گرافیکی. یک QA که کد نمینویسد میتواند تست ضبط کند، ویرایش کند، و اجرا کند — بدون اینکه یک خط کد بنویسد. در محیطهای سازمانی ایران که تیمهای QA اغلب ترکیبی از افراد فنی و غیرفنی هستند، این تفاوت بزرگی است.
مزیت نسبت به Playwright: یکپارچگی با تست موبایل، API و Desktop در یک ابزار. اگر اپلیکیشن شما چند کانال دارد، همه تستها در یک گزارش جمع میشوند.
محدودیت واقعی: TestComplete لایسنس تجاری دارد و برای پروژههای open-source مناسب نیست. اگر بودجه محدود است یا تیم توسعهدهنده هستید، Playwright گزینه بهتری است.
مرحله اول: فعالسازی Extension مرورگر
قبل از ضبط هر تستی، باید Extension TestComplete را در مرورگرتان فعال کنید.
برای Chrome:
- Chrome را باز کنید
- به آدرس
chrome://extensions/بروید - عبارت SmartBear TestComplete را جستجو کنید
- اگر Extension نصب نشده، از منوی TestComplete به مسیر زیر بروید:
Tools > Install Browser Extension > Google Chrome - بعد از نصب، روی آیکون Extension کلیک کنید و Enable را فعال کنید
برای Edge:
فرآیند مشابه است — TestComplete امکان نصب Extension برای Edge را هم از منوی Tools فراهم میکند.
نکته مهم: بعد از نصب Extension، Chrome یا Edge را کامل ببندید و دوباره باز کنید. TestComplete برای شناسایی مرورگر باید آن را خودش راهاندازی کند — اگر مرورگر از قبل باز باشد، ضبط تست درست کار نمیکند.
مرحله دوم: ضبط اولین تست وب
ایجاد پروژه
- TestComplete را باز کنید
- از منوی File گزینه New Project را انتخاب کنید
- نام پروژه را وارد کنید (مثلاً
WebLoginTest) - در بخش Project Type گزینه Web Testing را انتخاب کنید
- روی Finish کلیک کنید
شروع ضبط
- در نوار ابزار بالا روی دکمه Record (دایره قرمز) کلیک کنید
- پنجره Select Target Application باز میشود
- گزینه Web Browser را انتخاب کنید
- در فیلد URL آدرس اپلیکیشن وب خود را وارد کنید
- مرورگر هدف (Chrome یا Edge) را انتخاب کنید
- روی OK کلیک کنید
TestComplete مرورگر را باز میکند و نوار ضبط در پایین صفحه ظاهر میشود. از این لحظه، هر اتفاقی در مرورگر ضبط میشود.
انجام سناریوی ورود
فرض کنید میخواهیم تست ورود به سیستم را ضبط کنیم:
- روی فیلد نام کاربری کلیک کنید و مقدار
testuserرا تایپ کنید - روی فیلد رمز عبور کلیک کنید و
Test@1234را تایپ کنید - روی دکمه ورود کلیک کنید
- منتظر بمانید صفحه dashboard بارگذاری شود
- روی دکمه Stop در نوار ضبط کلیک کنید
TestComplete اسکریپت را تولید میکند. در پنل Script میتوانید کد تولیدشده را ببینید — اگر از JavaScript استفاده میکنید، چیزی شبیه به این خواهد بود:
function Test1()
{
var browser = Browsers.Item(btChrome);
browser.Run();
var page = browser.Page("https://example.com/login");
page.FindElement("//*[@id='username']").SetText("testuser");
page.FindElement("//*[@id='password']").SetText("Test@1234");
page.FindElement("//*[@id='loginBtn']").Click();
// بررسی ورود موفق
var dashboard = page.WaitPage("https://example.com/dashboard", 10000);
Log.Checkpoint(dashboard.Exists, "صفحه داشبورد بارگذاری شد");
}
💬 برای دریافت قیمت و مشاوره رایگان → همین الان در تلگرام پیام دهید — پاسخ در کمتر از چند ساعت
مرحله سوم: Object Repository و مدیریت عناصر
یکی از مهمترین مفاهیم در تست وب با TestComplete، Object Repository است. این بخش مرکزیترین نقطه مدیریت عناصر UI در پروژه شماست.
چرا Object Repository مهم است؟
وقتی تست ضبط میکنید، TestComplete هر عنصر را با یک selector شناسایی میکند — معمولاً ترکیبی از id، class، xpath یا ویژگیهای دیگر. اگر این selectorها مستقیماً در اسکریپتها پراکنده باشند، وقتی UI تغییر کند (که همیشه میکند)، باید تمام اسکریپتها را دستی پیدا و عوض کنید.
Object Repository این مشکل را حل میکند: عناصر را یک بار در یک مکان مرکزی تعریف میکنید، و همه اسکریپتها به همان مرجع اشاره میکنند. وقتی UI تغییر کرد، فقط Object Repository را آپدیت میکنید.
افزودن عنصر به Object Repository
- در پنل سمت چپ روی Object Repository کلیک کنید
- راستکلیک کنید و Add > New Item را انتخاب کنید
- پنجره Object Browser باز میشود
- مرورگر را به صفحه مورد نظر بروید
- روی عنصر مورد نظر (مثلاً فیلد نام کاربری) کلیک کنید
- TestComplete عنصر را شناسایی میکند و خصوصیات آن را نمایش میدهد
- یک نام معنادار برای عنصر وارد کنید (مثلاً
LoginPage_UsernameField) - روی Add کلیک کنید
استفاده از Object Repository در اسکریپت
بعد از تعریف عناصر، میتوانید در اسکریپت از آنها استفاده کنید:
function LoginTest()
{
// استفاده از Object Repository به جای selector مستقیم
var userField = NameMapping.Browsers.Chrome.LoginPage.UsernameField;
var passField = NameMapping.Browsers.Chrome.LoginPage.PasswordField;
var loginBtn = NameMapping.Browsers.Chrome.LoginPage.LoginButton;
userField.SetText("testuser");
passField.SetText("Test@1234");
loginBtn.Click();
}
مرحله چهارم: اعتبارسنجی عناصر صفحه
ضبط تست فقط نیمی از کار است. بخش مهمتر، Checkpoint هاست — جاهایی که بررسی میکنید صفحه آنچه باید را نشان میدهد.
Checkpoint انواع مختلف
۱. بررسی وجود عنصر:
// آیا پیام خوشآمدگویی نمایش داده شده؟
var welcomeMsg = page.FindElement("//*[@id='welcome-message']");
Log.Checkpoint(welcomeMsg.Exists, "پیام خوشآمدگویی نمایش داده شد");
۲. بررسی متن عنصر:
// آیا نام کاربر درست نمایش داده شده؟
var userNameDisplay = page.FindElement("//*[@id='user-display-name']");
Log.Checkpoint(
userNameDisplay.contentText === "کاربر تست",
"نام کاربر در داشبورد صحیح است"
);
۳. بررسی بارگذاری صفحه:
// بررسی URL بعد از ورود
var currentURL = Sys.Browser().Page("*").URL;
Log.Checkpoint(
aqString.Contains(currentURL, "/dashboard"),
"کاربر به داشبورد هدایت شد"
);
۴. Property Checkpoint گرافیکی:
برای کاربرانی که با اسکریپت راحت نیستند، TestComplete یک روش بصری هم دارد:
- در حین ضبط تست، روی دکمه Add Checkpoint در نوار ضبط کلیک کنید
- نوع Checkpoint را انتخاب کنید (Property، Region، Table و…)
- روی عنصر مورد نظر در مرورگر کلیک کنید
- مقدار مورد انتظار را وارد کنید
- TestComplete کد Checkpoint را خودکار تولید میکند
Checkpoint بصری (Image Comparison)
برای بررسی اینکه یک عنصر بصری درست نمایش داده میشود — مثلاً یک نمودار یا آیکون — میتوانید از Region Checkpoint استفاده کنید:
- در نوار ضبط روی Add Checkpoint > Region Checkpoint کلیک کنید
- با ماوس ناحیهای از صفحه را انتخاب کنید
- TestComplete یک تصویر baseline از آن ناحیه میگیرد
- در اجراهای بعدی، تصویر واقعی با baseline مقایسه میشود
توجه: Region Checkpoint به تغییرات فونت، رزولوشن و حالت dark/light حساس است. برای چکهای functional بهتر است از Property Checkpoint استفاده کنید.
مرحله پنجم: هندل کردن عناصر داینامیک
یکی از چالشهای اصلی تست وب، عناصر داینامیک هستند — عناصری که id یا class آنها در هر بارگذاری تغییر میکند، یا بعد از یک تأخیر ظاهر میشوند.
انتظار برای ظاهر شدن عنصر
// منتظر ماندن حداکثر ۱۵ ثانیه برای ظاهر شدن عنصر
var loadingComplete = page.WaitElement("//*[@id='data-table']", 15000);
if (loadingComplete.Exists) {
Log.Message("جدول داده بارگذاری شد");
} else {
Log.Error("جدول داده در زمان مقرر بارگذاری نشد");
}
مقابله با id های داینامیک
وقتی یک عنصر id داینامیک دارد (مثلاً input-1742635891), باید از ویژگیهای پایدارتر استفاده کنید:
// به جای id داینامیک، از ویژگیهای پایدار استفاده کنید
// مثلاً data-testid، aria-label، یا ترکیب tag + text
// جستجو با aria-label
var searchBtn = page.FindElement("//*[@aria-label='جستجوی محصول']");
// جستجو با text
var submitBtn = page.FindElement("//*[text()='ثبت سفارش']");
// جستجو با ترکیب class و position
var firstRow = page.FindElement("(//tr[@class='data-row'])[1]");
هندل کردن dropdown های داینامیک
function SelectDropdownOption(dropdownId, optionText)
{
var dropdown = page.FindElement("//*[@id='" + dropdownId + "']");
dropdown.Click(); // باز کردن dropdown
// انتظار برای ظاهر شدن آیتمهای dropdown
var option = page.WaitElement(
"//*[@class='dropdown-item'][text()='" + optionText + "']",
5000
);
if (option.Exists) {
option.Click();
Log.Message("گزینه '" + optionText + "' انتخاب شد");
} else {
Log.Error("گزینه '" + optionText + "' در dropdown پیدا نشد");
}
}
هندل کردن popup و alert
// هندل کردن JavaScript alert
function HandleAlert(acceptOrDismiss)
{
// TestComplete خودکار alert ها را تشخیص میدهد
var alert = page.Dialog;
if (alert.Exists) {
Log.Message("متن alert: " + alert.Message);
if (acceptOrDismiss === "accept") {
alert.Accept(); // کلیک روی OK
} else {
alert.Dismiss(); // کلیک روی Cancel
}
}
}
💬 برای دریافت قیمت و مشاوره رایگان → همین الان در تلگرام پیام دهید — پاسخ در کمتر از چند ساعت
مرحله ششم: Data-Driven Web Testing
تست data-driven یعنی یک سناریوی واحد را با دادههای مختلف اجرا کنیم. مثلاً تست ورود با ۱۰ کاربر مختلف، یا تست فرم ثبتنام با ترکیبهای مختلف ورودی.
روش اول: استفاده از Excel
یک فایل Excel بسازید با این ساختار:
| username | password | expected_result |
|---|---|---|
| user1 | Pass@1 | success |
| user2 | wrong | error |
| admin | Admin@99 | success |
در TestComplete این فایل را به پروژه اضافه کنید:
- در پنل Project Explorer راستکلیک کنید
- Add > New Item > Excel File را انتخاب کنید
- فایل Excel خود را انتخاب کنید
سپس در اسکریپت:
function DataDrivenLoginTest()
{
// خواندن داده از Excel
var excel = DDT.ExcelDriver(
ProjectSuite.Path + "\\TestData\\LoginData.xlsx",
"Sheet1",
true // خط اول header است
);
while (!excel.EOF()) {
var username = excel.Value("username");
var password = excel.Value("password");
var expected = excel.Value("expected_result");
// اجرای سناریوی ورود
RunLoginScenario(username, password, expected);
excel.Next();
}
excel.Close();
}
function RunLoginScenario(username, password, expectedResult)
{
var browser = Browsers.Item(btChrome);
browser.Navigate("https://example.com/login");
var page = browser.Page("*");
page.FindElement("//*[@id='username']").SetText(username);
page.FindElement("//*[@id='password']").SetText(password);
page.FindElement("//*[@id='loginBtn']").Click();
// بررسی نتیجه
if (expectedResult === "success") {
var dashboard = page.WaitElement("//*[@id='dashboard']", 10000);
Log.Checkpoint(dashboard.Exists, "ورود موفق برای کاربر: " + username);
} else {
var errorMsg = page.WaitElement("//*[@class='error-message']", 5000);
Log.Checkpoint(errorMsg.Exists, "پیام خطا برای کاربر نادرست: " + username);
}
}
روش دوم: استفاده از CSV
برای دادههای سادهتر، CSV فایل کافی است:
function LoadTestDataFromCSV()
{
var csv = DDT.CSVDriver(
ProjectSuite.Path + "\\TestData\\users.csv",
true, // خط اول header
"," // جداکننده
);
while (!csv.EOF()) {
Log.Message("تست با کاربر: " + csv.Value("username"));
// اجرای تست...
csv.Next();
}
csv.Close();
}
مرحله هفتم: Cross-Browser Testing
یکی از بزرگترین مزیتهای TestComplete، پشتیبانی بومی از چند مرورگر است. میتوانید همان تست را روی Chrome، Firefox، Edge و Safari (macOS) اجرا کنید.
اجرای تست روی مرورگرهای مختلف
function CrossBrowserLoginTest()
{
// لیست مرورگرهایی که میخواهیم تست کنیم
var browsers = [btChrome, btFirefox, btEdge];
var browserNames = ["Chrome", "Firefox", "Edge"];
for (var i = 0; i < browsers.length; i++) {
Log.AppendFolder("تست در مرورگر: " + browserNames[i]);
try {
var browser = Browsers.Item(browsers[i]);
browser.Navigate("https://example.com/login");
RunLoginScenario(browser, "testuser", "Test@1234");
Log.Message("تست در " + browserNames[i] + " موفق بود");
} catch(e) {
Log.Error("خطا در " + browserNames[i] + ": " + e.message);
}
Log.PopLogFolder();
}
}
تست با اندازههای مختلف صفحه (Responsive Testing)
function ResponsiveTest()
{
var browser = Browsers.Item(btChrome);
// تنظیمات سایزهای مختلف
var viewports = [
{ width: 1920, height: 1080, name: "Desktop Full HD" },
{ width: 1366, height: 768, name: "Laptop" },
{ width: 768, height: 1024, name: "Tablet" },
{ width: 375, height: 812, name: "Mobile iPhone" }
];
for (var i = 0; i < viewports.length; i++) {
var vp = viewports[i];
Log.AppendFolder("تست در: " + vp.name);
// تغییر اندازه پنجره مرورگر
browser.BrowserWindow(0).Maximize();
browser.BrowserWindow(0).Resize(vp.width, vp.height);
browser.Navigate("https://example.com");
// بررسی اینکه منوی hamburger در موبایل نمایش داده میشود
if (vp.width < 768) {
var hamburgerMenu = browser.Page("*").FindElement(
"//*[@class='hamburger-menu']"
);
Log.Checkpoint(
hamburgerMenu.Exists && hamburgerMenu.Visible,
"منوی موبایل در " + vp.name + " نمایش داده میشود"
);
}
Log.PopLogFolder();
}
}
مرحله هشتم: یکپارچگی با CI/CD
بعد از اینکه تستها آماده شدند، مرحله نهایی اجرای خودکار آنها در pipeline است.
اجرا از Command Line
TestComplete یک ابزار command-line به نام tcRunner دارد:
# اجرای یک تست مشخص
"C:\Program Files\SmartBear\TestComplete 15\Bin\TestComplete.exe" ^
"C:\Projects\WebTest\WebTest.pjs" ^
/run /project:WebLoginTest /test:LoginTests/DataDrivenLoginTest ^
/exit /exportlog:"C:\Results\TestLog.xml"
یکپارچگی با Jenkins
یک Jenkinsfile ساده برای تست وب:
pipeline {
agent { label 'windows-agent' }
stages {
stage('Web Tests') {
steps {
bat '''
"C:\\Program Files\\SmartBear\\TestComplete 15\\Bin\\TestComplete.exe" ^
"%WORKSPACE%\\WebTest.pjs" ^
/run /project:WebLoginTest ^
/exit /exportlog:"%WORKSPACE%\\Results\\TestLog.xml"
'''
}
}
stage('Publish Results') {
steps {
// پابلیش کردن نتایج XML
junit 'Results/*.xml'
}
}
}
post {
failure {
// ارسال ایمیل در صورت شکست
mail to: 'qa-team@yourcompany.com',
subject: "تست وب شکست خورد: ${env.JOB_NAME}",
body: "لینک نتایج: ${env.BUILD_URL}"
}
}
}
یکپارچگی با Azure DevOps
در فایل azure-pipelines.yml:
trigger:
branches:
include:
- main
- release/*
pool:
name: 'Windows Agents'
steps:
- task: CmdLine@2
displayName: 'Run TestComplete Web Tests'
inputs:
script: |
"C:\Program Files\SmartBear\TestComplete 15\Bin\TestComplete.exe" ^
"$(Build.SourcesDirectory)\WebTest.pjs" ^
/run /project:WebLoginTest ^
/exit /exportlog:"$(Build.ArtifactStagingDirectory)\TestResults.xml"
- task: PublishTestResults@2
displayName: 'Publish Test Results'
inputs:
testResultsFormat: 'JUnit'
testResultsFiles: '$(Build.ArtifactStagingDirectory)\TestResults.xml'
condition: always()
💬 برای دریافت قیمت و مشاوره رایگان → همین الان در تلگرام پیام دهید — پاسخ در کمتر از چند ساعت
نکات عملی و مشکلات رایج
مشکل ۱: TestComplete عنصر را پیدا نمیکند
علت معمول: عنصر هنوز بارگذاری نشده، یا selector تغییر کرده.
راهحل:
// به جای Find مستقیم، از WaitElement استفاده کنید
var element = page.WaitElement("//*[@id='myElement']", 10000);
if (!element.Exists) {
Log.Error("عنصر پس از ۱۰ ثانیه پیدا نشد");
return;
}
مشکل ۲: تست در CI/CD اجرا نمیشود
علت معمول: نیاز به session کاربری برای رابط گرافیکی.
راهحل: Agent باید با دسترسی interactive اجرا شود. در Jenkins:
- Agent را به عنوان service اجرا نکنید
- از
nssmیاWinSWبرای اجرا به عنوان desktop application استفاده کنید
مشکل ۳: تستها در Chrome آپدیت شده broken میشوند
علت معمول: آپدیت Chrome، Extension را غیرفعال میکند.
راهحل: بعد از هر آپدیت Chrome، دوباره به chrome://extensions/ بروید و مطمئن شوید Extension فعال است. در محیط CI، نسخه Chrome را pin کنید.
مشکل ۴: تستهای cross-browser زمان زیادی میبرند
راهحل: از TestComplete Distributed Testing استفاده کنید — میتوانید تستها را به صورت parallel روی چند ماشین اجرا کنید. این نیازمند لایسنس Distributed Testing است.
جمعبندی
در این مقاله یاد گرفتید که با TestComplete چطور:
- Extension مرورگر را راهاندازی کنید و اولین تست وب را ضبط کنید
- از Object Repository برای مدیریت متمرکز عناصر استفاده کنید
- انواع Checkpoint برای اعتبارسنجی عناصر صفحه بسازید
- عناصر داینامیک و popup ها را هندل کنید
- تستهای data-driven با Excel و CSV پیادهسازی کنید
- همان تست را روی Chrome، Firefox و Edge اجرا کنید
- تستها را به pipeline Jenkins یا Azure DevOps وصل کنید
این مقاله سومین بخش از سری TestComplete است — اگر هنوز تست API و تست موبایل را نخواندهاید، آنها را هم مطالعه کنید تا تصویر کاملتری از قابلیتهای TestComplete داشته باشید.
سوالات متداول (FAQ)
آیا TestComplete با Vue.js و React کار میکند؟
بله. TestComplete با هر اپلیکیشن وبی که در مرورگر اجرا میشود کار میکند — صرفنظر از فریمورک فرانتاند. برای SPA هایی که محتوا داینامیک بارگذاری میشود، باید از WaitElement و WaitProperty به جای دسترسی مستقیم استفاده کنید.
آیا میتوان تست وب را بدون کد نوشت؟
بله. TestComplete یک رابط Keyword Testing دارد که بدون نوشتن کد، با drag-and-drop و پارامترهای گرافیکی تست میسازید. مناسب برای اعضای تیم QA که توسعهدهنده نیستند.
تفاوت TestComplete با Selenium WebDriver چیست؟
Selenium open-source و code-first است — کنترل کامل دارید اما باید همه چیز را خودتان بنویسید. TestComplete یک ابزار تجاری با رابط گرافیکی است که ضبط تست، Object Repository بصری و گزارشدهی خودکار دارد. برای تیمهای ترکیبی (فنی + غیرفنی) TestComplete سریعتر به نتیجه میرسد.
آیا TestComplete از Shadow DOM پشتیبانی میکند؟
در نسخههای اخیر (14+) پشتیبانی از Shadow DOM اضافه شده. برای عناصر داخل Shadow DOM باید از FindElement با پارامتر SearchInShadowTree: true استفاده کنید.
TestComplete چند مرورگر همزمان تست میکند؟
با لایسنس پایه فقط یک مرورگر. با ماژول Distributed Testing میتوانید چند ماشین و چند مرورگر را به صورت parallel اجرا کنید.
آیا میتوان از TestComplete برای تست فرمهای فارسی (RTL) استفاده کرد؟
بله. TestComplete متن فارسی را در فیلدهای ورودی تنظیم میکند. فقط مطمئن شوید که encoding فایل اسکریپت UTF-8 است و محیط ویندوز از فارسی پشتیبانی میکند.
کدام نسخه TestComplete برای تست وب توصیه میشود؟
نسخه ۱۵ که جدیدترین نسخه در ۱۴۰۵ است. این نسخه پشتیبانی بهتری از Chrome 120+ و Edge Chromium دارد و باگهای Shadow DOM نسخههای قبلی در آن رفع شده.
خرید لایسنس اورجینال — مشاوره رایگان
قیمت دقیق بر اساس نسخه و تعداد کاربر متفاوت است. برای دریافت قیمت و راهنمایی رایگان با ما در تلگرام پیام دهید.
|
✓
+۲۰ سال تجربه
متخصصان مهندسی نرمافزار با سابقه بلندمدت
|
⚡
تحویل زیر ۲۴ ساعت
لایسنس شما ظرف یک روز کاری ارسال میشود
|
↩
ضمانت بازگشت وجه
در صورت عدم کارایی، مبلغ را کامل برمیگردانیم
|
پاسخ معمولاً در کمتر از چند ساعت — بدون پیشپرداخت برای مشاوره



