Best Python code snippet using localstack_python
test_role_utils.py
Source:test_role_utils.py  
1import unittest2import mock3from cgf_utils.test import mock_aws4from cgf_utils import role_utils5import time6from resource_manager_common import stack_info7from resource_manager_common.stack_info import StackInfo8from botocore.exceptions import ClientError9_STACK_INFO_MANAGER = stack_info.StackInfoManager()10class JSONStringEqualsDict(object):11    def __init__(self, dict):12        self.__dict = dict13    def __eq__(self, json_string):14        import json15        other_dict = json.loads(json_string)16        return self.__dict == other_dict17class UnitTest_CloudGemFramework_ProjectResourceHandler_role_utils_get_role_name(unittest.TestCase):18    def test_with_short_name(self):19        stack_arn = 'arn:aws:cloudformation:TestRegion:TestAccount:stack/ShortName-RandomPart/TestUUID'20        logical_role_name = 'RoleName'21        actual_role_name = role_utils.get_access_control_role_name(stack_arn, logical_role_name)22        self.assertEqual(actual_role_name, 'ShortName-RandomPart-RoleName')23    def test_with_too_long_name(self):24        stack_arn = 'arn:aws:cloudformation:TestRegion:TestAccount:stack/LongName9A123456789B123456789C123456789D123456789E123456789F123456789G-RandomPart/TestUUID'25        logical_role_name = 'RoleName9A123456789B123456789C123456789D123456789E123456789F123456789G'26        actual_role_name = role_utils.get_access_control_role_name(stack_arn, logical_role_name)27        self.assertEqual(actual_role_name, role_utils.sanitize_role_name('LongName9A123456789B123456789C123456789D123456789E123456789F123456789G-RandomPart-RoleName9A123456789B123456789C123456789D123456789E123456789F123456789G'))28class UnitTest_CloudGemFramework_ProjectResourceHandler_role_utils_create_access_control_role(unittest.TestCase):29    project_name = 'test-project-name'30    deployment_name = 'test-deployment-name'31    resource_group_name = 'test-resource-group-name'32    stack_arn = 'arn:aws:cloudformation:TestRegion:TestAccount:stack/ShortName-RandomPart/TestUUID'33    logical_role_name = 'test-logical-role-name'34    assume_role_service = 'test-assume-role-service'35    role_name = 'test-role-name'36    path = '/{project_name}/{deployment_name}/{resource_group_name}/{logical_role_name}/AccessControl/'.format(37        project_name=project_name,38        deployment_name=deployment_name,39        resource_group_name=resource_group_name,40        logical_role_name=logical_role_name)41    mock_stack_info = mock.MagicMock()42    mock_stack_info.deployment.project.project_name = project_name43    mock_stack_info.deployment.deployment_name = deployment_name44    mock_stack_info.resource_group_name = resource_group_name45    mock_stack_info.parameters = {'CloudCanvasStack': StackInfo.STACK_TYPE_RESOURCE_GROUP}46    mock_stack_info.stack_name = project_name47    mock_stack_info.stack_type = StackInfo.STACK_TYPE_RESOURCE_GROUP48    role_arn = 'test-role-arn'49    assume_role_policy_document = {50        "Version": "2012-10-17",51        "Statement": [52            {53                "Effect": "Allow",54                "Action": "sts:AssumeRole",55                "Principal": {56                    "Service": assume_role_service57                }58            }59        ]60    }61    assume_role_policy_document_matcher = JSONStringEqualsDict(assume_role_policy_document)62    create_role_response = {63        'Role': {64            'Arn': role_arn65        }66    }67    default_policy = 'test-policy'68    @mock_aws.patch_client('iam', 'create_role', return_value=create_role_response, reload=role_utils)69    @mock.patch('cgf_utils.role_utils.get_access_control_role_name', return_value=role_name)70    @mock.patch('resource_manager_common.stack_info.StackInfoManager.get_stack_info', return_value=mock_stack_info)71    def test_default(self, mock_get_stack_info, mock_get_access_control_role_name, mock_create_role):72        id_data = {}73        role_utils.PROPAGATION_DELAY_SECONDS = 274        start_time = time.clock()75        created_role_arn = role_utils.create_access_control_role(76            _STACK_INFO_MANAGER,77            id_data,78            self.stack_arn,79            self.logical_role_name,80            self.assume_role_service)81        stop_time = time.clock()82        delay_time = stop_time - start_time83        self.assertAlmostEqual(delay_time, role_utils.PROPAGATION_DELAY_SECONDS, delta=0.1)84        self.assertEqual(created_role_arn, self.role_arn)85        self.assertEquals(id_data, {'AbstractRoleMappings': {self.logical_role_name: self.role_name}})86        mock_get_access_control_role_name.assert_called_once_with(self.stack_arn, self.logical_role_name)87        mock_create_role.assert_called_once_with(RoleName=self.role_name,88                                                 AssumeRolePolicyDocument=self.assume_role_policy_document_matcher,89                                                 Path=self.path)90        mock_get_stack_info.assert_called_once_with(self.stack_arn)91    @mock_aws.patch_client('iam', 'create_role', return_value=create_role_response, reload=role_utils)92    @mock.patch('cgf_utils.role_utils.get_access_control_role_name', return_value=role_name)93    @mock.patch('resource_manager_common.stack_info.StackInfoManager.get_stack_info', return_value=mock_stack_info)94    def test_with_delay_for_propagation_false(self, mock_get_stack_info, mock_get_access_control_role_name,95                                              mock_create_role):96        id_data = {}97        role_utils.PROPAGATION_DELAY_SECONDS = 298        start_time = time.clock()99        created_role_arn = role_utils.create_access_control_role(100            _STACK_INFO_MANAGER,101            id_data,102            self.stack_arn,103            self.logical_role_name,104            self.assume_role_service,105            delay_for_propagation=False)106        stop_time = time.clock()107        delay_time = stop_time - start_time108        self.assertAlmostEqual(delay_time, 0, delta=0.1)109        self.assertEqual(created_role_arn, self.role_arn)110        self.assertEquals(id_data, {'AbstractRoleMappings': {self.logical_role_name: self.role_name}})111        mock_get_access_control_role_name.assert_called_once_with(self.stack_arn, self.logical_role_name)112        mock_create_role.assert_called_once_with(RoleName=self.role_name,113                                                 AssumeRolePolicyDocument=self.assume_role_policy_document_matcher,114                                                 Path=self.path)115        mock_get_stack_info.assert_called_once_with(self.stack_arn)116    @mock_aws.patch_client('iam', 'create_role', return_value=create_role_response, reload=role_utils)117    @mock_aws.patch_client('iam', 'put_role_policy', return_value={})118    @mock.patch('cgf_utils.role_utils.get_access_control_role_name', return_value=role_name)119    @mock.patch('resource_manager_common.stack_info.StackInfoManager.get_stack_info', return_value=mock_stack_info)120    def test_with_default_policy(self, mock_get_stack_info, mock_get_access_control_role_name, mock_put_role_policy,121                                 mock_create_role):122        id_data = {}123        created_role_arn = role_utils.create_access_control_role(124            _STACK_INFO_MANAGER,125            id_data,126            self.stack_arn,127            self.logical_role_name,128            self.assume_role_service,129            delay_for_propagation=False,130            default_policy=self.default_policy)131        self.assertEqual(created_role_arn, self.role_arn)132        self.assertEquals(id_data, {'AbstractRoleMappings': {self.logical_role_name: self.role_name}})133        mock_get_access_control_role_name.assert_called_once_with(self.stack_arn, self.logical_role_name)134        mock_create_role.assert_called_once_with(RoleName=self.role_name,135                                                 AssumeRolePolicyDocument=self.assume_role_policy_document_matcher,136                                                 Path=self.path)137        mock_put_role_policy.assert_called_once_with(RoleName=self.role_name, PolicyName='Default',138                                                     PolicyDocument=self.default_policy)139        mock_get_stack_info.assert_called_once_with(self.stack_arn)140class UnitTest_CloudGemFramework_ProjectResourceHandler_role_utils_delete_access_control_role(unittest.TestCase):141    policy_name_1 = 'policy_name_1'142    policy_name_2 = 'policy_name_2'143    list_role_policies_response = {144        'PolicyNames': [policy_name_1, policy_name_2]145    }146    delete_role_policy_response = {147    }148    delete_role_response = {149    }150    no_such_entity_response = {151        'Error': {152            'Code': 'NoSuchEntity'153        }154    }155    access_denied_response = {156        'Error': {157            'Code': 'AccessDenied'158        }159    }160    unknown_error_code = 'test-error-code'161    other_error_response = {162        'Error': {163            'Code': unknown_error_code164        }165    }166    resource_group_stack_arn = 'test-resource-group-stack-arn'167    logical_role_name = 'test-logical-role-name'168    role_name = 'test-role-name'169    @mock_aws.patch_client('iam', 'list_role_policies', return_value=list_role_policies_response, reload=role_utils)170    @mock_aws.patch_client('iam', 'delete_role_policy', return_value=delete_role_policy_response)171    @mock_aws.patch_client('iam', 'delete_role', return_value=delete_role_response)172    def test_with_no_errors(self, mock_delete_role, mock_delete_role_policy, mock_list_role_policies):173        id_data = {'AbstractRoleMappings': {self.logical_role_name: self.role_name}}174        role_utils.delete_access_control_role(id_data, self.logical_role_name)175        self.assertEquals(id_data, {'AbstractRoleMappings': {}})176        mock_list_role_policies.assert_called_once_with(RoleName=self.role_name)177        mock_delete_role_policy.assert_any_call(RoleName=self.role_name, PolicyName=self.policy_name_1)178        mock_delete_role_policy.assert_any_call(RoleName=self.role_name, PolicyName=self.policy_name_2)179        mock_delete_role.assert_called_once_with(RoleName=self.role_name)180    @mock_aws.patch_client('iam', 'list_role_policies',181                           side_effect=ClientError(no_such_entity_response, 'list_role_policies'), reload=role_utils)182    @mock_aws.patch_client('iam', 'delete_role_policy', return_value=delete_role_policy_response)183    @mock_aws.patch_client('iam', 'delete_role', return_value=delete_role_response)184    def test_with_list_role_policies_no_such_entity_error(self, mock_delete_role, mock_delete_role_policy,185                                                          mock_list_role_policies):186        id_data = {'AbstractRoleMappings': {self.logical_role_name: self.role_name}}187        role_utils.delete_access_control_role(id_data, self.logical_role_name)188        self.assertEquals(id_data, {'AbstractRoleMappings': {}})189        mock_list_role_policies.assert_called_once_with(RoleName=self.role_name)190        mock_delete_role.assert_called_once_with(RoleName=self.role_name)191    @mock_aws.patch_client('iam', 'list_role_policies',192                           side_effect=ClientError(access_denied_response, 'list_role_policies'), reload=role_utils)193    @mock_aws.patch_client('iam', 'delete_role_policy', return_value=delete_role_policy_response)194    @mock_aws.patch_client('iam', 'delete_role', return_value=delete_role_response)195    def test_with_list_role_policies_access_denied_error(self, mock_delete_role, mock_delete_role_policy,196                                                         mock_list_role_policies):197        id_data = {'AbstractRoleMappings': {self.logical_role_name: self.role_name}}198        role_utils.delete_access_control_role(id_data, self.logical_role_name)199        self.assertEquals(id_data, {'AbstractRoleMappings': {}})200        mock_list_role_policies.assert_called_once_with(RoleName=self.role_name)201        mock_delete_role.assert_called_once_with(RoleName=self.role_name)202    @mock_aws.patch_client('iam', 'list_role_policies',203                           side_effect=ClientError(other_error_response, 'list_role_policies'), reload=role_utils)204    @mock_aws.patch_client('iam', 'delete_role_policy', return_value=delete_role_policy_response)205    @mock_aws.patch_client('iam', 'delete_role', return_value=delete_role_response)206    def test_with_list_role_policies_other_error(self, mock_list_role_policies, mock_delete_role,207                                                 mock_delete_role_policy):208        id_data = {'AbstractRoleMappings': {self.logical_role_name: self.role_name}}209        with self.assertRaisesRegexp(ClientError, self.unknown_error_code):210            role_utils.delete_access_control_role(id_data, self.logical_role_name)211        self.assertEquals(id_data, {'AbstractRoleMappings': {self.logical_role_name: self.role_name}})212        mock_list_role_policies.assert_called_once_with(RoleName=self.role_name)213    @mock_aws.patch_client('iam', 'list_role_policies', return_value=list_role_policies_response, reload=role_utils)214    @mock_aws.patch_client('iam', 'delete_role_policy',215                           side_effect=ClientError(no_such_entity_response, 'delete_role_policy'))216    @mock_aws.patch_client('iam', 'delete_role', return_value=delete_role_response)217    def test_with_delete_role_policy_no_such_entity_error(self, mock_delete_role, mock_delete_role_policy,218                                                          mock_list_role_policies):219        id_data = {'AbstractRoleMappings': {self.logical_role_name: self.role_name}}220        role_utils.delete_access_control_role(id_data, self.logical_role_name)221        self.assertEquals(id_data, {'AbstractRoleMappings': {}})222        mock_list_role_policies.assert_called_once_with(RoleName=self.role_name)223        mock_delete_role_policy.assert_any_call(RoleName=self.role_name, PolicyName=self.policy_name_1)224        mock_delete_role_policy.assert_any_call(RoleName=self.role_name, PolicyName=self.policy_name_2)225        mock_delete_role.assert_called_once_with(RoleName=self.role_name)226    @mock_aws.patch_client('iam', 'list_role_policies', return_value=list_role_policies_response, reload=role_utils)227    @mock_aws.patch_client('iam', 'delete_role_policy',228                           side_effect=ClientError(access_denied_response, 'delete_role_policy'))229    @mock_aws.patch_client('iam', 'delete_role', return_value=delete_role_response)230    def test_with_delete_role_policy_access_denied_error(self, mock_delete_role, mock_delete_role_policy,231                                                         mock_list_role_policies):232        id_data = {'AbstractRoleMappings': {self.logical_role_name: self.role_name}}233        role_utils.delete_access_control_role(id_data, self.logical_role_name)234        self.assertEquals(id_data, {'AbstractRoleMappings': {}})235        mock_list_role_policies.assert_called_once_with(RoleName=self.role_name)236        mock_delete_role_policy.assert_any_call(RoleName=self.role_name, PolicyName=self.policy_name_1)237        mock_delete_role_policy.assert_any_call(RoleName=self.role_name, PolicyName=self.policy_name_2)238        mock_delete_role.assert_called_once_with(RoleName=self.role_name)239    @mock_aws.patch_client('iam', 'list_role_policies', return_value=list_role_policies_response, reload=role_utils)240    @mock_aws.patch_client('iam', 'delete_role_policy',241                           side_effect=ClientError(other_error_response, 'delete_role_policy'))242    @mock_aws.patch_client('iam', 'delete_role', return_value=delete_role_response)243    def test_with_delete_role_policy_other_error(self, mock_list_role_policies, mock_delete_role_policy,244                                                 mock_delete_role):245        print '===', mock_list_role_policies, mock_delete_role, mock_delete_role_policy246        id_data = {'AbstractRoleMappings': {self.logical_role_name: self.role_name}}247        with self.assertRaisesRegexp(ClientError, self.unknown_error_code):248            role_utils.delete_access_control_role(id_data, self.logical_role_name)249        self.assertEquals(id_data, {'AbstractRoleMappings': {self.logical_role_name: self.role_name}})250        mock_delete_role_policy.assert_any_call(RoleName=self.role_name, PolicyName=self.policy_name_1)251        mock_list_role_policies.assert_called_once_with(RoleName=self.role_name)252    @mock_aws.patch_client('iam', 'list_role_policies', return_value=list_role_policies_response, reload=role_utils)253    @mock_aws.patch_client('iam', 'delete_role_policy', return_value=delete_role_policy_response)254    @mock_aws.patch_client('iam', 'delete_role', side_effect=ClientError(no_such_entity_response, 'delete_role'))255    def test_with_delete_role_no_such_entity_error(self, mock_delete_role, mock_delete_role_policy,256                                                   mock_list_role_policies):257        id_data = {'AbstractRoleMappings': {self.logical_role_name: self.role_name}}258        role_utils.delete_access_control_role(id_data, self.logical_role_name)259        self.assertEquals(id_data, {'AbstractRoleMappings': {}})260        mock_list_role_policies.assert_called_once_with(RoleName=self.role_name)261        mock_delete_role_policy.assert_any_call(RoleName=self.role_name, PolicyName=self.policy_name_1)262        mock_delete_role_policy.assert_any_call(RoleName=self.role_name, PolicyName=self.policy_name_2)263        mock_delete_role.assert_called_once_with(RoleName=self.role_name)264    @mock_aws.patch_client('iam', 'list_role_policies', return_value=list_role_policies_response, reload=role_utils)265    @mock_aws.patch_client('iam', 'delete_role_policy', return_value=delete_role_policy_response)266    @mock_aws.patch_client('iam', 'delete_role', side_effect=ClientError(access_denied_response, 'delete_role'))267    def test_with_delete_role_access_denied_error(self, mock_delete_role, mock_delete_role_policy,268                                                  mock_list_role_policies):269        id_data = {'AbstractRoleMappings': {self.logical_role_name: self.role_name}}270        role_utils.delete_access_control_role(id_data, self.logical_role_name)271        self.assertEquals(id_data, {'AbstractRoleMappings': {}})272        mock_list_role_policies.assert_called_once_with(RoleName=self.role_name)273        mock_delete_role_policy.assert_any_call(RoleName=self.role_name, PolicyName=self.policy_name_1)274        mock_delete_role_policy.assert_any_call(RoleName=self.role_name, PolicyName=self.policy_name_2)275        mock_delete_role.assert_called_once_with(RoleName=self.role_name)276    @mock_aws.patch_client('iam', 'list_role_policies', return_value=list_role_policies_response, reload=role_utils)277    @mock_aws.patch_client('iam', 'delete_role_policy', return_value=delete_role_policy_response)278    @mock_aws.patch_client('iam', 'delete_role', side_effect=ClientError(other_error_response, 'delete_role'))279    def test_with_delete_role_other_error(self, mock_delete_role, mock_delete_role_policy, mock_list_role_policies):280        id_data = {'AbstractRoleMappings': {self.logical_role_name: self.role_name}}281        with self.assertRaisesRegexp(ClientError, self.unknown_error_code):282            role_utils.delete_access_control_role(id_data, self.logical_role_name)283        self.assertEquals(id_data, {'AbstractRoleMappings': {self.logical_role_name: self.role_name}})284        mock_delete_role_policy.assert_any_call(RoleName=self.role_name, PolicyName=self.policy_name_1)285        mock_delete_role_policy.assert_any_call(RoleName=self.role_name, PolicyName=self.policy_name_2)286        mock_list_role_policies.assert_called_once_with(RoleName=self.role_name)287class UnitTest_CloudGemFramework_ProjectResourceHandler_role_utils_get_access_control_role_arn(unittest.TestCase):288    resource_group_stack_arn = 'test-resource-group-stack-arn'289    logical_role_name = 'test-logical-role-name'290    role_name = 'test-role-name'291    role_arn = 'test-role-arn'292    get_role_response = {293        'Role': {294            'Arn': role_arn295        }296    }297    @mock_aws.patch_client('iam', 'get_role', return_value=get_role_response, reload=role_utils)298    def test_default(self, mock_get_role):299        id_data = {'AbstractRoleMappings': {self.logical_role_name: self.role_name}}300        actual_role_arn = role_utils.get_access_control_role_arn(id_data, self.logical_role_name)301        self.assertEquals(actual_role_arn, self.role_arn)...test_update_lambda.py
Source:test_update_lambda.py  
1import importlib2import io3import json4from unittest import mock5import pytest6MODULE = "lambda.update_lambda"7update_lambda = importlib.import_module(MODULE)8@pytest.fixture9def context():10    return mock.Mock(aws_request_id="request_1234")11@mock.patch(f"{MODULE}.get_region_cidrs")12@mock.patch(f"{MODULE}.cfnresponse")13def test_lambda_handler(mock_cfnresponse, mock_get_region_cidrs, boto3, context, monkeypatch):14    monkeypatch.setenv("iam_role_name", "role_1234")15    client = boto3.client("iam")16    client.list_role_policies.return_value = {17        "PolicyNames": ["foo", "bar"]18    }19    mock_get_region_cidrs.return_value = ["10.0.0.0/8"]20    event = {"ResponseURL": "https://example.com"}21    update_lambda.lambda_handler(event, context)22    client.put_role_policy.assert_called_once()23    client.delete_role_policy.assert_any_call(RoleName="role_1234", PolicyName="foo")24    client.delete_role_policy.assert_any_call(RoleName="role_1234", PolicyName="bar")25    mock_cfnresponse.send.assert_called_once_with(event, context, mock_cfnresponse.SUCCESS, {"Data": mock.ANY})26@mock.patch(f"{MODULE}.get_region_cidrs")27@mock.patch(f"{MODULE}.cfnresponse")28def test_lambda_handler_no_response(mock_cfnresponse, mock_get_region_cidrs, boto3, context, monkeypatch):29    monkeypatch.setenv("iam_role_name", "role_1234")30    client = boto3.client("iam")31    client.list_role_policies.return_value = {32        "PolicyNames": ["foo", "bar"]33    }34    mock_get_region_cidrs.return_value = ["10.0.0.0/8"]35    event = {}36    update_lambda.lambda_handler(event, context)37    client.put_role_policy.assert_called_once()38    client.delete_role_policy.assert_any_call(RoleName="role_1234", PolicyName="foo")39    client.delete_role_policy.assert_any_call(RoleName="role_1234", PolicyName="bar")40    mock_cfnresponse.send.assert_not_called()41@mock.patch(f"{MODULE}.get_region_cidrs")42@mock.patch(f"{MODULE}.cfnresponse")43def test_lambda_handler_no_policy_names(mock_cfnresponse, mock_get_region_cidrs, boto3, context):44    client = boto3.client("iam")45    client.list_role_policies.return_value = {}46    mock_get_region_cidrs.return_value = ["10.0.0.0/8"]47    event = {}48    update_lambda.lambda_handler(event, context)49    client.put_role_policy.assert_called_once()50    client.delete_role_policy.assert_not_called()51    mock_cfnresponse.send.assert_not_called()52@mock.patch(f"{MODULE}.get_region_cidrs")53@mock.patch(f"{MODULE}.cfnresponse")54def test_lambda_handler_error(mock_cfnresponse, mock_get_region_cidrs, context):55    mock_get_region_cidrs.side_effect = Exception("mock exception")56    event = {"ResponseURL": "https://example.com"}57    update_lambda.lambda_handler(event, context)58    mock_cfnresponse.send.assert_called_once_with(event, context, mock_cfnresponse.FAILED, {"Data": mock.ANY})59@mock.patch(f"{MODULE}.get_region_cidrs")60@mock.patch(f"{MODULE}.cfnresponse")61def test_lambda_handler_error_no_response(mock_cfnresponse, mock_get_region_cidrs, context):62    mock_get_region_cidrs.side_effect = Exception("mock exception")63    event = {}64    update_lambda.lambda_handler(event, context)65    mock_cfnresponse.send.assert_not_called()66@mock.patch(f"{MODULE}.urllib.request")67def test_get_region_cidrs(mock_request):68    data = json.dumps({69        "prefixes": [70            # Correct service and region71            {72                "ip_prefix": "10.10.0.0/24",73                "service": "AMAZON",74                "region": "us-east-1"75            },76            # Wrong service77            {78                "ip_prefix": "10.20.0.0/24",79                "service": "SOMETHING_ELSE",80                "region": "us-east-1"81            },82            # Wrong region83            {84                "ip_prefix": "10.30.0.0/24",85                "service": "AMAZON",86                "region": "us-west-2"87            },88            # Two prefixes that should be merged89            {90                "ip_prefix": "10.40.0.0/24",91                "service": "AMAZON",92                "region": "us-east-1"93            },94            {95                "ip_prefix": "10.40.0.0/16",96                "service": "AMAZON",97                "region": "us-east-1"98            },99        ]100    }).encode()101    mock_request.urlopen.return_value = io.BytesIO(data)102    ips = update_lambda.get_region_cidrs("us-east-1")103    assert ips == [104        "10.10.0.0/24",105        "10.40.0.0/16",106        "10.0.0.0/8"107    ]108def test_get_base_policy(monkeypatch):109    monkeypatch.setenv("vpcid", "vpc_1234")110    policy = update_lambda.get_base_policy("prefix_1234")111    assert isinstance(policy, dict)112    for statement in policy["Statement"]:113        for resource in statement["Resource"]:...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
