Over the past 7.2 years, I've had the privilege of working extensively in the realm of Quality Assurance, where I've honed my skills across various testing processes. My tenure as a Technical Test Lead at Infosys has provided me with a robust foundation in both manual and automated testing, covering areas such as System, Integration, End to End, UAT, Regression, Sanity, Functional & API testing.
One of my key strengths lies in automation testing, where I've leveraged tools and frameworks like Selenium, TestNG, PyTest, Rest Assured, Playwright-JS, and Node JS to craft hybrid frameworks tailored to project requirements. Notably, I've spearheaded the development of Node JS-based automation applications/tools for complex healthcare processes, significantly reducing manual effort and enhancing efficiency.
I've had the privilege of leading critical projects, such as the delivery of complex B2B healthcare transactions and the automation of various healthcare processes, including web and mobile automation.
Currently working as a QAE in Amazon RING team.
Technical Test Lead
Infosys Ltd.Selenium
TestNG
Node JS
Jenkins
AWS
GitHub
Cucumber
SOAP UI
Postman
JMeter
Confluence
Docker
Kubernetes
Prometheus
Grafana
API system into an. So
The dynamic elements as efficiently as possible using the, uh, efficient ways or explicit rate. And also, uh, if, uh, if, um, uh, can, uh, I can also use retry mechanisms if, uh, if there is a failure of any test cases while running the test suites, um, after that. So in that case, in fact, uh, the the flakiness could be of could be of could be because of any external factors. So, uh, to make sure that, uh, it doesn't we do not really know whether it is happening for some other, like, whether this is happening for because of the code or something. So what we can do is we can definitely try we can retry the test case, uh, try running the test case again so that maybe it, uh, dropped the process process successfully.
Yeah. So, uh, one thing that we need to ensure while creating those, uh, selling up test is that we do not hard code anything, uh, which, uh, yeah, which would hard code any values that is, uh, that we are, uh, trying to test. And, uh, you know, to make sure that it's scalable. Uh, if something changes depending upon, uh, the data shouldn't be restrict. Like, the test wouldn't be restrict to a particular data. Then use should be test the test cases should be created in such a way that any any data can be used for, uh, for the functionality for any specific functionality for new build test case. So it should be written in such a way that it's easily scalable. And, uh, yeah, I mean, shouldn't it be those hardware values or any and it's any sorts? Uh, whatever values that you should be, uh, which would be used, it should come from the function itself, which in the function, the test cases will be written that so that so that it can take any value. And, also, we can do, uh, and, also, we can ensure that whatever locators we are using, uh, it is generic. It's not, uh, it's it's not specific to a particular it's not specific to a particular element, uh, or locator. Or we If if there are any elements that has been added in the future, it should it should be able to handle that as well. So make sure that the locators are properly handled. You can use stars, you know, from if you're using XPath to locate an element, then it's just, uh, you can use a star from, uh, as a star, then you can, uh, trace the path accordingly so that if at all there is any change, uh, down, I should be able to handle it.
Synchronization issues. Okay? Mhmm. So synchronizing issue mainly happens because, uh, um, because of, uh, dynamic elements. If if any dynamic elements found and tries to tries to process those elements with before the tag and rendered in the in in the town. In those case, we have good synchronization issues. So what you can do is the best option would be to use weight of maybe making mechanisms. Uh, can use, uh, implicit weights for an overall for overall, uh, test test case. Uh, but if you if there are any elements which are if there are multiple elements when, uh, stored or multiple elements being created, then we can use an explicit way to handle that specific, uh, DOM element. In that case, we can efficiently, uh, fix that, uh, synchronization issues. We can also use thread slip. That is not a mechanism I it's recommended, uh, because it's really pauses. So it really stops the execution for a certain time, which is not efficient in a way. But, yeah, what you can do is, uh, in order to debug the scripts, if you wanna debug the scripts, you can definitely use a standard script. Uh, Once that is once we have been once it has been debugged and wanted to call, uh, once the specific, uh, locator or anything, what what what on which the, uh, external or implicit in it's little implicit we want to apply, uh, it's been taken care of, then we can definitely, uh, get rid of the, uh, And yeah. So the best option, uh, option would be to use location explicit, but also sometimes you can use also. Is also a good option.
So the preferred way to manage the project I would be working with CICD is to, uh, uh, is to parameterize them, actually. I mean, uh, we can we can yeah. We're using Jenkins. We can parameterize, uh, uh, like, you can parameterize the the browser drivers, be it, uh, you wanna run you wanna run you wanna process the test cases in a specific browser, you can parameterize it. And, uh, yeah, push it to the, like, uh, pass it to the Ruby script itself. Uh, and depending upon that, uh, whatever parameter is imposed, uh, depending upon that, uh, the the code should have the code ready. Code the code should be ready to handle those, uh, depending upon that. Uh, whatever is coming from the command line, it should be able to handle it. Uh, the coach will be able to handle those things. That's the best approach we can follow right now here in our c s c pipeline. You can parameterize, uh, browser drivers, definitely. So, uh, depending upon what type of browser you wanna run, you can, uh, get pasted in the command, uh, checking, uh, pass it in the checking command. And, uh, yeah, that's that that specific flag of driver browser type is being hand is being kept or in the should be caught in the code. And depending on what type of it, what type of browser it has been passed, uh, from the command command line, should the code should be ready to handle it. And Accordingly, it processed in a specific
Yeah. So if you're getting to a particular specific, uh, yeah, I was going to make sure that, uh, before running the Jenkins, we're gonna make sure that, uh, that, uh, specific test has been run locally, before the build is generated properly. Uh, so so that make sure, uh, to ensure that there is no job failures, that they should be, uh, yeah, uh, to make sure that the build is successful. So we can put we can, uh, use different mechanisms as mentioned before. I can retry that, uh, you you can retry that, uh, to retry mechanisms, uh, if there is job failure. Uh, it it might be it might happen because of some sporadic issues. It does on, uh, connectivity issues have get a lot of external factors coming to fetch, which, uh, can, uh, make a relentless to fail. So by by using retry mechanisms, you can can handle it. You hand you can read read to get the same test case, which has been which has failed. Yeah. But before before before that, we need to make ensure that, um, the score is is is appropriate. It is able to handle, uh, this, uh, the specific type of scenarios properly, and, uh, it's run runs without any errors.
Syntax, uh, overall the stuff schema and stuff looks appropriate, but, uh, I think we're missing out on the specific, uh, credential details. Like, uh, we should be using the credentials. Right? Uh, the the the variables that needs to go, uh, that we need to pass it to the step definitions. Uh, there are no variables over here. So it should be, like, even the user end on the login page, and then the user enters the valid credentials using username. Username will be the username should be one of the variables and passwords should be one of the variables. So so that, uh, data, uh, what has been, uh, what has been, uh, used in the second, the text code should pass should will get passed to the step definitions. And whatever functionality that you want to provide inside that, you can provide it. So So I think that that, uh, parameter that, uh, credential parameter is missing, that should fix it.
Yeah. So in this case, what we can do is we can use implicit weights, uh, to wait for the elements to properly get loaded. We can also use explicit weight, but, uh, since but we can handle this with explicit wait itself. I can wait for, uh, 3rd, 10 seconds, maybe 20 seconds Put a weight of duration of 20 seconds, uh, so that the the all those elements get properly loaded, web elements get properly loaded. And we don't wanna miss out any, uh, the I mean, the code doesn't miss out on anything. So we can put our explicit wait wait before. Uh, Yeah. Uh, we can wait. Uh, we can put in we can add an implicit wait just after the driver dot get, uh, statement, uh, so that before we enter the, uh, using it, so to make sure that the all those DOM elements or the implements get properly worked before, uh, making operations on it.
So, the most optimal approach to get a maintainable, scannable framework would be to use a phobject model. So, where we segregate or we structure the specific framework into page, different types of page that we are about to test in the Selenium. That would, like all those functionalities of it, if it is a login functionality, everything, all those functional function related to login will go inside the login page. All those functionalities of the dashboard will go to the dashboard, so each, every other, like all those pages have been, all those functionalities on the pages or test cases on the particular page has been handled separately. So what we are about to do is, it becomes a, I mean, you can reuse, you can reuse and yeah, so what we can do is, all those locators that is going into the specific, for the specific page, you can add it to the page object, page objects, and there with, on that, on therein, you can call those functions, like create functions, in functions or whatever actions you want to perform, you can perform, you can use those, you can create those functions. Then one more thing is, if particular special functionalities, if the particular functionality is generic, like it's, if you feel that this can be reused again and again, for example, a waiting mechanism, it's over, it's waiting mechanism is, it's somewhat, it's very generic, right? So what we can do, we can put in a utility functions where you can utilize it as many as number of times, yeah, it's been created, you can create a class, and you can create a, then you can define a function, wherein the, you can pass in the specific, like, you can pass in the specific element, by, be it a by element, or be it a driver element, web element. So that we can pass that, we can call that particular specific function by inheriting that utility class, and can reuse as many, as many number of times as possible. And, yeah, hard coding is a big no, in, for a specific framework, so that it can take any values, it should be, it should be, we should create the functions, function should be created in a very scalable manner, like, not hard code any values, it should take in the arguments, the arguments should be very understandable, should maintain the consistency. And you can use like, yeah, Jenkins, when building the framework, you can also parameterize the, parameterize the value, like, depending upon what type of browser you want to run it, by using parameterizing concept in the Jenkins. Yeah, you can do that. Yeah, that's how we maintain scalability, like, test properly and make sure that it is stable.
Yeah. So, uh, since it is, uh, the agile environment, uh, agile environment, uh, So it would really greatly impact like, uh, my creation of a test resilient test frameworks will really depend upon, uh, how the sprint moves. So we so, uh, if we, uh, do a lot of instrument automation, uh, and, uh, it so it always, uh, since we have to create a lot of automation, so it always happens that when, uh, if, uh, the manual testing is happening or function function testing is happening on sprint a. And but, uh, the automation, uh, go the automation, uh, will follow approach a minus 1. Like, it it will go 1 it will be, uh, moving, uh, one sprint, uh, behind so that we can, uh, once that functionalities have been, uh, deployed properly, can you we can go we can check we can automate those automate those functionalities. Uh, so, uh, definitely, uh, definitely, uh, because, uh, depending upon the type of, uh, type of the com the complexity, depending upon the the estimation, the story estimation, uh, story points. We have to, uh, make we have to, uh, make sure how to structure a framework properly, uh, so that, uh, we can efficiently have to automate those conflicts, uh, within the time time line.
Yeah. So mentoring the junior test testers into automation of complex scenario, uh, it's, uh, it's really challenging, of course. And and we need to really we need to know really smartly because we got a strict, uh, timelines. And within the fixed time, we have to, uh, implement those changes. So what, uh, my approach would be, I, uh, I need to make sure that the knowledge impact, uh, for the changes is really proper so that they understand what understand the changes that we or the scope that we need to automate. That is really important. Just going blind stick won't won't help. Uh, just, uh, it would just drag us down. Uh, secondly, the comp since it is a complex test and then the complex test scenario, just dividing segregating into the smaller chunks and, uh, smaller functionalities, uh, so that it is so that in that case, what we can do is that we can achieve, uh, maintainability and scalability as well. And, also, once we once the complex test scenario can segregate it into smaller chunks into smaller modules, uh, so, uh, it becomes easier for easier for that junior test to understand how to implement those changes.