December 31, 2015

Automate Amazon: Writing a Sign In Test

This post is fourth of a series of nine. Need to go back to the beginning?

Drafting a Login Test for Amazon.com won't be as easy as drafting one for Dave Haeffner's mock site, The-Internet. There needs to be a lot more infrastructure put in place besides the CommonUtils library we worked on in the last blog post. Also, Amazon.com use the word "Login". Instead, they use the phrase Sign In.


Sketch the SignIn Steps

Here's how you log into sign into Amazon.com's site:
  1. Go to Amazon.com's home page, http://www.amazon.com/
  2. Hover your cursor over the "Your Account" block, and click the sign in button.
  3. Once you are on the sign in page, enter the username, password into the appropriate text boxes. 
  4. Select the Sign In button. 
I noticed after following this process a few times, that there sometimes was a bit of a lag, so we might want to wait until the username and password actually appear before entering a username and password. 

Review: How to find selectors of Web Elements

Let's say we want to know about what selectors to use for the username, password, and Sign In button on the Sign In page.

You can find the ids and cssSelectors of an object by:
  • Opening the Firefox browser with the Firebug and Firepath plugin. 
  • Going to http://www.amazon.com/ and pressing the "Sign In" button.
  • Right clicking and selecting on the textboxes or the button and selecting "Inspect in Firepath".
  • With the "Firepath" tab, make sure "CSS" is selected. 
We can see that the following web elements have these values:
  • Email textbox: cssSelector #ap_email
  • Password textbox: cssSelector #ap_password
  • Sign In Button: cssSelector #signInSubmit
... Yes, these values are technically IDs and not CSS Selectors. Adding the '#' makes them CSS Selectors. At my workplace, I find that IDs of web elements are constantly changing, since the ID is usually a numbered index. CSS Values seem to change less, so I got in the habit of leaning towards CSS Selectors over IDs. 


Sketch out the Infrastructure Needed

Judging from what we have listed above, we will need the following classes written:
  • A Test Class, PurchaseOrderTest, that stores the tests.
  • A class to store the username and password of test users, and a class to retrieve the data.
  • Methods in CommonUtilites that handle sending keys to textboxes, clicking on buttons, and hovering-and-clicking on sections of the home page.
  • Two classes called Page Objects to store how the HomePage and the LoginPage interacts with the DOM.
  • We can bundle together commonly used methods in an Actions class, and call it OrderActions.

What our Directory Structure Will Look Like


After we store the User Properties, create the Actions classes, and create the test class, our directory structure could look like:

src/test/java

  • actions
    • OrderActions
  • base
    • LoadProperties
  • pages
    • HomePage
    • SignInPage
  • properties
    • user.properties
  • testcases
    • PurchaseOrderTest
  • utils
    • CommonUtils
    • DriverUtils



Store the User Properties


Store the Username and Password in a text file called a Properties file, user.properties. Create a class called LoadProperties in order to handle the reading and the writing of the file. (Code formatting from http://codeformatter.blogspot.com/).

java / properties / user.properties:
1:  tester23.username=amzn.tester23@gmail.com  
2:  tester23.password=amzntester23  

java / base / LoadProperties.java
1:  package base;  
2:  import org.apache.commons.lang3.StringUtils;  
3:  import java.io.FileInputStream;  
4:  import java.io.FileNotFoundException;  
5:  import java.io.IOException;  
6:  import java.util.Properties;  
7:  import java.util.Set;  
8:  /**  
9:   * Created by tmaher on 12/22/2015.  
10:   */  
11:  public class LoadProperties {  
12:    public static Properties user = loadProperties("src/test/java/properties/user.properties");  
13:    private static Properties loadProperties(String filePath) {  
14:      Properties properties = new Properties();  
15:      try {  
16:        FileInputStream f = new FileInputStream(filePath);  
17:        properties.load(f);  
18:      } catch (FileNotFoundException e) {  
19:        e.printStackTrace();  
20:      } catch (IOException e){  
21:        e.printStackTrace();  
22:      }  
23:      return properties;  
24:    }  
25:    public static String getPropertyValue(String path, String key){  
26:      Properties p = loadProperties(path);  
27:      String result = "";  
28:      Set<String> values = p.stringPropertyNames();  
29:      for(String value : values){  
30:        if(StringUtils.equalsIgnoreCase(value, key)){  
31:          result = p.getProperty(value);  
32:          break;  
33:        }  
34:      }  
35:      return result;  
36:    }  
37:  }  
All Source Code can be found in T.J. Maher's Automate-Amazon repository. 

Next, we can work from the bottom level to the top:
  • Adding methods to CommonUtils
  • Abstracting each page into a PageObject such as HomePage and SignInPage
  • Bundling the methods in the PageObjects to create repeatable Actions we can use.
  • Compose the Actions methods into a test we can run. 

1. Add to CommonUtil 

Add to CommonUtils methods the basic building blocks our page objects will call. All Selenium WebDriver calls will be encapsulated in a method on CommonUtils.

  • Navigate to a URL

 public void navigateToURL(String URL) {  
     try {  
       _driver.navigate().to(URL);  
     } catch (Exception e) {  
       System.out.println("FAILURE: URL did not load: " + URL);  
       throw new TestException("URL did not load");  
     }  
   }  

  • SendKeys to a Textbox, given the web element by selector, and the value.

 public void sendKeys(By selector, String value) {  
     WebElement element = getElement(selector);  
     clearField(element);  
     try {  
       element.sendKeys(value);  
     } catch (Exception e) {  
       throw new TestException(String.format("Error in sending [%s] to the following element: [%s]", value, selector.toString()));  
     }  
 }  

  • Click on a button, given the web element by selector

 public void click(By selector) {  
     WebElement element = getElement(selector);  
     waitForElementToBeClickable(selector);  
     try {  
       element.click();  
     } catch (Exception e) {  
       throw new TestException(String.format("The following element is not clickable: [%s]", selector));  
     }  
   }  

  • Hovers a cursor over a web element and click it
 public void scrollToThenClick(By selector) {  
     WebElement element = _driver.findElement(selector);  
     actions = new Actions(_driver);  
     try {  
       ((JavascriptExecutor) _driver).executeScript("arguments[0].scrollIntoView(true);", element);  
       actions.moveToElement(element).perform();  
       actions.click(element).perform();  
     } catch (Exception e) {  
       throw new TestException(String.format("The following element is not clickable: [%s]", element.toString()));  
     }  
   }  


  • Waits Until an Element is Visible
 public void waitForElementToBeVisible(By selector) {  
     try {  
       wait = new WebDriverWait(_driver, timeout);  
       wait.until(ExpectedConditions.presenceOfElementLocated(selector));  
     } catch (Exception e) {  
       throw new NoSuchElementException(String.format("The following element was not visible: %s", selector));  
     }  
   }  

2. Page Objects

Now that the Selenium WebDriver functionality has been encapsulated, we can extend the page objects to use CommonUtils. We are inheriting from CommonUtilites the above methods.

These Page Objects are the only places that should interact with the web elements on the page, evaluating if the web elements are there, checking and setting their values.

On the top of each Page Object, we have the selectors for each web element. They are each declared private because they are only to be accessed in this page object. They are also declared final because they are constant.

By is a reserved word in the Selenium library. Web elements can be found By.id, By.cssSelector, By.name, etc.



HomePage:
1:  package pages;  
2:  import enums.Url;  
3:  import org.openqa.selenium.By;  
4:  import utils.CommonUtils;  
5:  /**  
6:   * Created by tmaher on 12/21/2015.  
7:   */  
8:  public class HomePage extends CommonUtils {  
9:    private final By YOUR_ACCOUNT = By.id("nav-link-yourAccount");  
10:    private final By SHOPPING_CART_ICON = By.cssSelector("#nav-cart");  
11:    private final By SHOPPING_CART_COUNT = By.cssSelector("#nav-cart > #nav-cart-count");  
12:    public HomePage(){  
13:    }  
14:    public void navigateToHomePage() {  
15:      String url = Url.BASEURL.getURL();  
16:      System.out.println("Navigating to Amazon.com: " + url);  
17:      navigateToURL(url);  
18:    }  
19:    public void navigateToSignInPage(){  
20:      System.out.println("HOME_PAGE: Selecting [YOUR_ACCOUNT] in navigation bar.");  
21:      scrollToThenClick(YOUR_ACCOUNT);  
22:      System.out.println("HOME_PAGE: Navigating to the SIGNIN_PAGE.\n");  
23:    }  
24:  }  

SignInPage:
1:  package pages;  
2:  import org.openqa.selenium.By;  
3:  import utils.CommonUtils;  
4:  /**  
5:   * Created by tmaher on 12/21/2015.  
6:   */  
7:  public class SignInPage extends CommonUtils {  
8:    private final By USERNAME = By.cssSelector("#ap_email");  
9:    private final By PASSWORD = By.cssSelector("#ap_password");  
10:    private final By SIGNIN_BUTTON = By.cssSelector("#signInSubmit");  
11:    public void enterUsername(String userName){  
12:      System.out.println("SIGNIN_PAGE: Entering username: " + userName);  
13:      waitForElementToBeVisible(USERNAME);  
14:      sendKeys(USERNAME, userName);  
15:    }  
16:    public void enterPassword(String password){  
17:      System.out.println("SIGNIN_PAGE: Entering password.");  
18:      waitForElementToBeVisible(PASSWORD);  
19:      sendKeys(PASSWORD, password);  
20:    }  
21:    public void clickSignInButton(){  
22:      System.out.println("SIGNIN_PAGE: Clicking the [SIGN_IN] button.\n");  
23:      click(SIGNIN_BUTTON);  
24:    }  
25:  }  

3. Actions Classes

When someone enters a username into the SignIn page, it's a safe bet that they are going to want to enter a password, too, along with clicking on the SignIn button. If someone wants to write a test that explicitly asserts that yes, we can enter text into the username textbox, they can do that by accessing the SignIn page object. But most of the time, those three methods will be grouped together.

Below, we group them together in a method called loginAs(String username, String password). Pass in a username and password, and it will do the rest.

OrderActions.java
1:  package actions;  
2:  import pages.*;  
3:  /**  
4:   * Created by tmaher on 12/21/2015.  
5:   */  
6:  public class OrderActions {  
7:    public void navigateToHomePage(){  
8:      HomePage homePage = new HomePage(); // Instantiate a new HomePage page object 
9:      homePage.navigateToHomePage();  
10:    }  
11:    public void loginAs(String username, String password){  
12:      HomePage homePage = new HomePage();  // Instantiate a new HomePage page object 
13:      SignInPage signIn = new SignInPage();  // Instantiate a new SignInPage page object 
14:      homePage.navigateToSignInPage();  
15:      signIn.enterUsername(username);  // Use the methods on the SignInPage
16:      signIn.enterPassword(password);  
17:      signIn.clickSignInButton();  
18:    }  
19:  }  


4. PurchaseOrderTest: test_Login

Now that we have all the components, we can start assembling the pieces in the Actions class to form a test.

PurchaseOrderTest.java
1:  package testcases;  
2:  import base.LoadProperties;  
3:  import org.openqa.selenium.WebDriver;  
4:  import actions.*;  
5:  import org.testng.annotations.AfterClass;  
6:  import org.testng.annotations.BeforeClass;  
7:  import org.testng.annotations.Test;  
8:  import utils.DriverUtils;  
9:  import static org.testng.Assert.assertEquals;  
10:  /**  
11:   * Created by tmaher on 12/14/2015.  
12:   */  
13:  public class PurchaseOrderTest {  
14:    public WebDriver driver;  
15:    @BeforeClass  
16:    public void setUp(){  
17:      driver = DriverUtils.getDriver();  
18:    }  
19:    @Test()  
20:    public void test_Login(){  
21:      OrderActions orderActions = new OrderActions();  
22:      String username = LoadProperties.user.getProperty("tester23.username");  
23:      String password = LoadProperties.user.getProperty("tester23.password");  
24:      orderActions.navigateToHomePage();  
25:      orderActions.loginAs(username, password);  
26:   
27:    }  
28:    @AfterClass  
29:    public void tearDown(){  
30:      driver.quit();  
31:    }  
32:  }  
All Source Code can be found in T.J. Maher's Automate-Amazon repository. 


5. Run the Test


Now that everything is all set, we can right click on the test method for test_Login and run the test:

 Navigating to Amazon.com: http://www.amazon.com  
 HOME_PAGE: Selecting [YOUR_ACCOUNT] in navigation bar.  
 HOME_PAGE: Navigating to the SIGNIN_PAGE.  
 SIGNIN_PAGE: Entering username: amzn.tester23@gmail.com  
 SIGNIN_PAGE: Entering password.  
 SIGNIN_PAGE: Clicking the [SIGN_IN] button.  
All Source Code can be found in T.J. Maher's Automate-Amazon repository. 

... Normally, we would then assert if we are on the correct page or not. I didn't add that into the test since what I really wanted to do was the next blog entry.

Until then, happy coding!

View the (mostly) Completed Test Code:


NEXT: Setup Objects to Handle Various Products, such as Books! >> 


-T.J. Maher
 Sr. QA Engineer, Fitbit
 Boston, MA

// Automated tester for [ 8 ] month and counting!

Please note: 'Adventures in Automation' is a personal blog about automated testing. It is not an official blog of Fitbit.com



268 comments:

«Oldest   ‹Older   201 – 268 of 268
divy said...

great article to read Digital Marketing Company In Pune, Digital Marketing services In Pune ,Digital Marketing Agency In Pune

Digitmarket said...

Hello dear blogger,
you did a perfect job here. I like your blog post, after I read it, I have notice that the tutorial is perfect. That is good, Thanks a lot.
Data Analytics Qualifications

karanm said...

Hello, this article about writing a test on sign in for Amazon is very informational. The javascript mentioned is noteworthy. I'll be saving this for reference. Keep posting more such useful content.
Data Analytics VS Data Science

RDataAnalyst said...

For me this article was really excellent in explanations filled with code instances with detailed notes and directory structure with complete technical step by step points to learn new ideas here. If anyone wants to learn Data Analyst Salary In India then kindly join the newly designed curriculum professional course with highly demanded skills. You will be taught in a professional environment with the given practical assignments which you can decide in your specialized stream. Data Analyst Salary In India

ananya said...

Hi, there is no doubt that it's a valuable and informative blog post. I really appreciate your work.
Visit- CA Coaching in Mumbai

tradeachievers said...

Wow!! Amazing article. The info shared here is completely wonderful and valuable to the rookies who wish to learn more about the subject in deep. I have never gone through an article like this before. This inspires me to learn more. Thanks for the share. Keep posting more wonderful insights with us. Anyone interested in learning about trading in Chennai, feel free to contact us. Best online trading courses in Chennai

financial India said...

Great article to automate amazon sign in.. Extremely knowledgeable. Keep up the good work Best Financial modeling courses in India

Seventh said...

Hi blogger,
I just want to thank you for this valuable work you have done for millions of users. Keep doing the good work. Best SEO Courses in India

gst course said...

Amazing blog on automation in amazon Best GST Courses in India

Devanshi said...

Thank you for sharing this blog. it's very useful.
check out Digital Marketing Training in pune

Lastweek said...

HI dear blogger,
I was really glad to find your article inhere. I found as a great adventure as you mentioned in the tittle. It is a great blog post to read, very informative. Best Content Writing Courses in India

RGSTcourse said...

The article on Software QA engineers looks knowledgeable in shifting from manual to automated testing to which I made a bookmark of it. Also, if anyone is interested in learning more about Best GST Courses in India, then I would like to recommend you with this article on the Best GST Courses in India – A Detailed Exposition With Live Training. Best GST Courses in India

Anonymous said...

The topic is very informative and interesting to read.Thank you for explaining the topic in such a easy manner.
solar ups distributors

Nithya said...

You have done a great job in writing this blog, and it is a great read. I appreciate the effort you have taken to explain the process of writing a sign-in test for Amazon in a detailed manner. The step-by-step guide was very helpful for me to understand the process. The detailed information and the tips you provided have been really helpful. You have given me a better understanding of the process. Thank you for the great article. Best Technical Writing Courses in India

Shambavi MG said...

You have done a fantastic job in writing this blog! It was very helpful to read about the process of automating Amazon writing sign in test. Your step-by-step instructions made it easy to understand and follow. I think your article will be very useful for many people who are looking for an easy way to automate their Amazon writing sign in test. I appreciate your effort in making this information accessible and easy to understand. Thank you for sharing your knowledge with us. FMVA

divy said...

good to read
Teamcenter Training in Pune

Anonymous said...

good to read the article.

Teamcenter Training in Pune

divy said...

Fantastic article
Teamcenter Training in Pune

dataanalyticscoursesinkenya said...

Hi amazing blog. Very informative and well written. You have explained all the steps precisely. Thanks a lot for sharing this information.
Data Analytics Courses in Kenya

Divya said...

You have done an amazing job in explaining how to automate Amazon writing sign in test. You have provided step by step instructions which makes it easy to understand and follow. You have also highlighted the mistakes which should be avoided while writing test cases. Your blog is really helpful and I appreciate the effort you have put into making it. Article Writing

Thendral said...

This article is very interesting and has valuable content. Thanks for sharing.
Best Tally Courses in India

Abinash Dash said...

Great blog. Thanks for sharing your views with us. The demand of digital marketing is rapidly growing. Know more best digital marketing training in Noida

kells said...

Your articles show how important automation is for us. the world is going digital and automated. To know more about it visit us at Digital marketing course in Gurgaon

Yozar dorji said...

Thank you for the view it has got a lot of meaning in it. you can also check with the Digital marketing course in Gurgaon

myblog said...

Awesome post! This is an awesome experience for me. I really enjoyed your blog. I would like to read more. Thanks for sharing such an amazing content. Keep sharing. And please visit ! Best Business Accounting & Taxation Course in India 

Pooja said...

You did a great job in writing this blog. It is very helpful to understand the automation of Amazon writing sign in test and how to go about it. You have clearly explained each step and provided screenshots to help the reader understand the process. The step by step instructions make it easier to follow. You have also highlighted the importance of writing good test cases. I appreciate the effort you have put in to write this blog and I'm sure it will be of great use to many. Thank you for writing this. Best Technical Writing Courses in India

Viswa said...

Nice Blog

Advanced Excel Training in Chennai
Online Advanced Excel Training

SWATHI said...

Thank you for writing this blog, you! This is an incredibly useful and well-written guide on how to automate Amazon writing sign-in tests. Your step-by-step instructions are easy to understand and follow and are a helpful resource for anyone looking to take their Amazon writing skills to the next level. I appreciate the time and effort you put into creating this and sharing it with others. Digital Marketing Courses in Glassglow

Anonymous said...

Hey Fabulous Article got to learned so much about it. Thankyou for sharing the Article on this subject. “ Adventures in Automation” gives us great deal of information about the subject. Keep producing such great content and keep it up.
Adventures in Automation
Digital Marketing Courses in Austria

sailender said...

Best explanation on automation by using firepath plugin.Easy representation of steps and directory structure.
Digital Marketing Courses In Centurion

hp said...

The way you explain the complex topic that easily is truly amazing.
Digital Marketing Courses In Norwich

Unknown said...

very easy to understand thankyou for the knowledge checkout digital marketing course in nashik
https://edupract.in/

Viswa said...

Nice Blog

Training and Placement Institute in Chennai
Online Placement Training

roopa said...

Great content! Love the way you put it very understandable.
Best Data analytics courses in India

Vilmams said...

Great. I really enjoyed reading this piece of information. Thanks for sharing this. Digital Marketing Courses In zaria 

Free data Analytics courses said...

Amazing blog post. You have given detailed explanation on creating a sign up/ login similar to Amazon. It is very interesting and helpful. Thank you for sharing this information. I would like to read more posts from you. Please check this link Free data Analytics courses

Babu said...

Very useful information. Brilliant writing and clear explanation. Thanks for sharing this brilliant article. I really adore your work. Digital Marketing Courses In Doha

hnp said...

Thankyou for explaining the whole topic so easily.
Digital Marketing Courses In geelong

Steven Carl said...

Nice to review your message as it consists of enjoyable and credible information and facts with all the realities.Umrah Packages
All About Modern World
All Write
Writer Talks
All About Modern World

Sumathu said...

Nice Blog

Core Java Training in Chennai

Usman Amjad said...

Owings for this particular instructive as well as helpful write. I am considerably happy to determine this type of guidance on your blog.

We Print Boxes
Custom Boxes
Boxes for Sale

Seoprac said...

Great article on how to Automate Amazon. It gives you a step-by-step process on how to do it. Very happy to come across this.

Digital Marketing Courses In hobart

jessy aram said...

This post is very simple to read and appreciate without leaving any details out. Great work!
Digital branding

dmpassion04 said...

The "Adventures of Automation" blog is a great resource for anyone interested in automation and its applications in various industries.
Benefits of Online digital marketing course

myra said...

This post is very informative and provided valuable insights on the topic. I appreciate the effort you put into researching and writing this. Keep up the good work!
Digital marketing tips for small businesses

Gayathri said...

Informative article! Must appreciate your efforts in writing.
Best Free online digital marketing courses

Bonnymocha23 said...

Perfect article on hwo to Automate Amazon. It has been very helpful.

Top ways to get started with a career in marketing

Anonymous said...

This is a pretty fascinating site, demonstrating the effort you put into creating one of the greatest to read blogs. also read Best December Umrah Packages 2023

hnp said...

Kudos to the content. Thanks for sharing this article.
How Digital marketing is changing business

Softcrayons said...


Excellent! “Your blog post was incredibly engaging and well-written! I appreciate the level of detail and research you put into your writing. It's evident that you have a deep understanding of the topic, and your insights were enlightening. Thank you for sharing such valuable information!"
I am a Digital Marketing Trainer at Digital Marketing Training Institute Noida providing best digital marketing training at an affordable price with highly qualified and experienced trainers.


Softcrayons said...

"Excellent post! Well-written, insightful analysis with practical examples and engaging style. Informative and enjoyable to read. Looking forward to more content from you. Keep up the great work!" I am a trainer at Softcrayons Tech Solution Pvt Ltd providing Google Analytics Training Noida at an affordable price. Join our training program today to learn from the best in the industry!

Digital Marketing Courses In Atlanta said...

Outstanding work. I really like your article. I will be looking forward for more articles from you. It is very relevant to the topic. It shows your hardwork and dedication. Keep it up.
Digital Marketing Courses In Atlanta

howdigitalmarketingworks said...

Very useful and informative blog
How Digital marketing works

padma said...

This article will provide accurate and contemporary information about social media marketing and advertising. 
 Social media marketing and advertising 

Moumita said...

This article provides clear and concise instructions on how to perform a sign-in test on Amazon.com and how to find the selectors for the necessary web elements. The tips on using CSS selectors over IDs are helpful for ensuring consistency in testing.
Types of digital marketing which is ideal

dmpassion05 said...

The blog offers a wealth of knowledge and insights on the latest trends and best practices in automation testing, making it an indispensable resource for software testers and automation enthusiasts looking to stay ahead of the curve
Social media marketing ideas

Sukhavasi said...

The post is well-structured and provides useful information that can be applied in real-world scenarios. Overall, this is a valuable resource for anyone interested in automating tests for Amazon Writing Sign-In.

Meaning of social media marketing a guide for beginners

Praveena said...

Great blog post. I found it really useful. Thank you for sharing this information.
Adwords marketing

Praveena said...

A very informative blog post. Thank you for sharing this information.
Digital Marketing Courses In Dublin

FMmarketing said...

Thank you for such a detailed post on this topic.
Facebook Marketing has taken the Digital Marketing world by a storm. Know more about it in this article.
 Facebook marketing all you ever wanted to know 

dmpassion06 said...

Thanks for taking your own time to discuss this topic, I feel happy about that curiosity has increased to learn more about this topic.
Top 12 free email-marketing tools for business

My Homes Fix said...

Automating the process of writing a Sign In test for Amazon can greatly streamline the testing process. 🤖📝 By automating this crucial step, you can ensure consistent and reliable testing of the sign-in functionality, saving time and effort in the long run. ⏱️🔧 An efficient way to enhance the quality and efficiency of your testing efforts! 🚀👍 #AutomationTesting #SignInSection #EfficiencyBoost Best AC Repair in Sharjah

hsp90 said...

Very knowledgeable blog!
Digital marketing agencies in Noida

niharika said...

Wow, what an insightful and informative blog post! I truly appreciate the depth of knowledge and clarity with which you've presented the topic. It's evident that you've put a lot of effort into researching and crafting this valuable content. Thank you for sharing such valuable insights and practical tips. This blog has definitely expanded my understanding and will be a great resource for anyone looking to delve into this subject. Keep up the fantastic work!
Benefits of a Digital marketing course

Moumita said...

Great job on breaking down the steps to automate the sign-in process for Amazon! Your clear explanations and well-organized directory structure make it easy to follow along. This article provides a valuable resource for anyone looking to automate their tests on Amazon.

Top benefits of using social media for business


DigitalMarketingCoursesKolkata said...

Very interesting, Wish to see much more like this. Thanks for sharing your information!
Digital marketing courses In Kolkata

Aleen Ali said...

Your Blog is very nice.Wish to see much more like this. Thanks for sharing your information
Marketing Automation

Gautam Goyal said...

Hi, I really enjoyed your blog. It was very informative. Thank you for sharing this information. .Top 5 computer courses after 10th in ahmedabad

«Oldest ‹Older   201 – 268 of 268   Newer› Newest»