├── .editorconfig
├── .gitignore
├── DockerFile
├── README.md
├── checkstyle
├── checkstyle-suppressions.xml
└── checkstyle.xml
├── db.json
├── jobportal-0.0.1-SNAPSHOT.jar
├── lombok.config
├── pom.xml
├── src
├── main
│ ├── java
│ │ └── com
│ │ │ └── automation
│ │ │ ├── annotations
│ │ │ └── FrameworkAnnotation.java
│ │ │ ├── config
│ │ │ ├── ConfigFactory.java
│ │ │ └── FrameworkConfig.java
│ │ │ ├── constants
│ │ │ ├── FCWithSingleton.java
│ │ │ └── FrameworkConstants.java
│ │ │ ├── enums
│ │ │ ├── Authors.java
│ │ │ ├── CategoryType.java
│ │ │ └── ConfigProperties.java
│ │ │ ├── exceptions
│ │ │ ├── FrameworkException.java
│ │ │ └── ReportInitializationException.java
│ │ │ ├── listeners
│ │ │ ├── Listeners.java
│ │ │ └── RetryFailedTests.java
│ │ │ ├── models
│ │ │ ├── builders
│ │ │ │ ├── RequestBuilder.java
│ │ │ │ └── ResponseBuilder.java
│ │ │ └── pojo
│ │ │ │ ├── Employee.java
│ │ │ │ ├── Skill.java
│ │ │ │ ├── Student.java
│ │ │ │ └── StudentBuilder.java
│ │ │ ├── reports
│ │ │ ├── ExtentLogger.java
│ │ │ ├── ExtentManager.java
│ │ │ └── ExtentReport.java
│ │ │ └── utils
│ │ │ ├── ApiUtils.java
│ │ │ ├── AssertionKeys.java
│ │ │ ├── AssertionUtils.java
│ │ │ ├── ExcelUtils.java
│ │ │ ├── FakerUtils.java
│ │ │ ├── JiraUtils.java
│ │ │ ├── PropertyHelper.java
│ │ │ ├── PropertyUtils.java
│ │ │ └── RandomUtils.java
│ └── resources
│ │ └── log4j2.properties
└── test
│ ├── java
│ └── com
│ │ └── automation
│ │ ├── practice
│ │ ├── DownloadFileTest.java
│ │ ├── GetRequestTest.java
│ │ ├── auth
│ │ │ ├── BasicAuthTest.java
│ │ │ ├── BearerTokenTest.java
│ │ │ ├── CookieBasedAuthentication.java
│ │ │ └── DigestAuthTest.java
│ │ ├── builderpattern
│ │ │ └── BuilderDesignPatternTest.java
│ │ ├── ergast
│ │ │ └── ExtractResponseTest.java
│ │ ├── jsonserver
│ │ │ ├── ConstructPostRequestTest.java
│ │ │ ├── CustomApiUsingJsonServerTest.java
│ │ │ ├── EndToEndTest.java
│ │ │ ├── GetRequestTest.java
│ │ │ ├── PostRequestDataDrivenExcelTest.java
│ │ │ ├── PostRequestUsingPojoTest.java
│ │ │ └── UpdateRequestTest.java
│ │ ├── postmanecho
│ │ │ ├── FormUrlEncodedTest.java
│ │ │ ├── MultiPartFormDataTest.java
│ │ │ └── QueryParametersTest.java
│ │ ├── reqres
│ │ │ ├── DeleteRequestTest.java
│ │ │ ├── GetAPITest.java
│ │ │ ├── PatchRequestTest.java
│ │ │ ├── PathParameterTest.java
│ │ │ └── PutRequestTest.java
│ │ └── wiremock
│ │ │ ├── SpecifyingRequestPortTest.java
│ │ │ ├── XmlNamespaceValidationTest.java
│ │ │ └── XmlSchemaValidationTest.java
│ │ └── tests
│ │ ├── DeleteParticularJobIdTest.java
│ │ ├── GetJobDetailsTest.java
│ │ ├── GetRequestWithBasicAuthTest.java
│ │ ├── GetRequestWithQueryParamsTest.java
│ │ ├── HeadRequestTest.java
│ │ ├── JsonSchemaValidationTest.java
│ │ ├── PatchRequestToUpdateParticularJobIdTest.java
│ │ ├── PostJobDetailsTest.java
│ │ ├── PutRequestToUpdateJobDetailsTest.java
│ │ └── ResponseAwareMatcherTest.java
│ └── resources
│ ├── config
│ └── config.properties
│ ├── data
│ ├── PostData.xlsx
│ └── TestData.xlsx
│ ├── json
│ ├── create_job_details.json
│ ├── json-schema.json
│ └── update_job_details.json
│ ├── test.json
│ ├── wiremock
│ ├── __files
│ │ ├── file.xml
│ │ └── student.xml
│ ├── mappings
│ │ ├── stub1.json
│ │ ├── stub2.json
│ │ └── stub3.json
│ └── wiremock-jre8-standalone-2.33.1.jar
│ └── xml
│ ├── xml-dtd-schema.dtd
│ └── xml-xsd-schema.xsd
└── testng.xml
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | end_of_line = lf
6 | indent_size = 4
7 | indent_style = space
8 | insert_final_newline = true
9 | max_line_length = 120
10 | tab_width = 4
11 | ij_continuation_indent_size = 8
12 | ij_formatter_off_tag = @formatter:off
13 | ij_formatter_on_tag = @formatter:on
14 | ij_formatter_tags_enabled = false
15 | ij_smart_tabs = false
16 | ij_visual_guides = none
17 | ij_wrap_on_typing = false
18 |
19 | [*.java]
20 | indent_size = 2
21 | max_line_length = 136
22 | tab_width = 2
23 | ij_continuation_indent_size = 2
24 | ij_java_align_consecutive_assignments = false
25 | ij_java_align_consecutive_variable_declarations = false
26 | ij_java_align_group_field_declarations = false
27 | ij_java_align_multiline_annotation_parameters = false
28 | ij_java_align_multiline_array_initializer_expression = false
29 | ij_java_align_multiline_assignment = false
30 | ij_java_align_multiline_binary_operation = false
31 | ij_java_align_multiline_chained_methods = false
32 | ij_java_align_multiline_extends_list = false
33 | ij_java_align_multiline_for = true
34 | ij_java_align_multiline_method_parentheses = false
35 | ij_java_align_multiline_parameters = true
36 | ij_java_align_multiline_parameters_in_calls = true
37 | ij_java_align_multiline_parenthesized_expression = false
38 | ij_java_align_multiline_records = true
39 | ij_java_align_multiline_resources = true
40 | ij_java_align_multiline_ternary_operation = false
41 | ij_java_align_multiline_text_blocks = false
42 | ij_java_align_multiline_throws_list = false
43 | ij_java_align_subsequent_simple_methods = false
44 | ij_java_align_throws_keyword = false
45 | ij_java_annotation_parameter_wrap = off
46 | ij_java_array_initializer_new_line_after_left_brace = false
47 | ij_java_array_initializer_right_brace_on_new_line = false
48 | ij_java_array_initializer_wrap = normal
49 | ij_java_assert_statement_colon_on_next_line = false
50 | ij_java_assert_statement_wrap = normal
51 | ij_java_assignment_wrap = normal
52 | ij_java_binary_operation_sign_on_next_line = false
53 | ij_java_binary_operation_wrap = normal
54 | ij_java_blank_lines_after_anonymous_class_header = 0
55 | ij_java_blank_lines_after_class_header = 0
56 | ij_java_blank_lines_after_imports = 1
57 | ij_java_blank_lines_after_package = 1
58 | ij_java_blank_lines_around_class = 1
59 | ij_java_blank_lines_around_field = 0
60 | ij_java_blank_lines_around_field_in_interface = 0
61 | ij_java_blank_lines_around_initializer = 1
62 | ij_java_blank_lines_around_method = 1
63 | ij_java_blank_lines_around_method_in_interface = 1
64 | ij_java_blank_lines_before_class_end = 0
65 | ij_java_blank_lines_before_imports = 1
66 | ij_java_blank_lines_before_method_body = 0
67 | ij_java_blank_lines_before_package = 0
68 | ij_java_block_brace_style = end_of_line
69 | ij_java_block_comment_add_space = false
70 | ij_java_block_comment_at_first_column = true
71 | ij_java_builder_methods = none
72 | ij_java_call_parameters_new_line_after_left_paren = false
73 | ij_java_call_parameters_right_paren_on_new_line = false
74 | ij_java_call_parameters_wrap = normal
75 | ij_java_case_statement_on_separate_line = true
76 | ij_java_catch_on_new_line = false
77 | ij_java_class_annotation_wrap = split_into_lines
78 | ij_java_class_brace_style = end_of_line
79 | ij_java_class_count_to_use_import_on_demand = 999
80 | ij_java_class_names_in_javadoc = 1
81 | ij_java_do_not_indent_top_level_class_members = false
82 | ij_java_do_not_wrap_after_single_annotation = false
83 | ij_java_do_while_brace_force = never
84 | ij_java_doc_add_blank_line_after_description = true
85 | ij_java_doc_add_blank_line_after_param_comments = false
86 | ij_java_doc_add_blank_line_after_return = false
87 | ij_java_doc_add_p_tag_on_empty_lines = true
88 | ij_java_doc_align_exception_comments = true
89 | ij_java_doc_align_param_comments = true
90 | ij_java_doc_do_not_wrap_if_one_line = false
91 | ij_java_doc_enable_formatting = true
92 | ij_java_doc_enable_leading_asterisks = true
93 | ij_java_doc_indent_on_continuation = false
94 | ij_java_doc_keep_empty_lines = true
95 | ij_java_doc_keep_empty_parameter_tag = true
96 | ij_java_doc_keep_empty_return_tag = true
97 | ij_java_doc_keep_empty_throws_tag = true
98 | ij_java_doc_keep_invalid_tags = true
99 | ij_java_doc_param_description_on_new_line = false
100 | ij_java_doc_preserve_line_breaks = false
101 | ij_java_doc_use_throws_not_exception_tag = true
102 | ij_java_else_on_new_line = false
103 | ij_java_enum_constants_wrap = normal
104 | ij_java_extends_keyword_wrap = normal
105 | ij_java_extends_list_wrap = normal
106 | ij_java_field_annotation_wrap = split_into_lines
107 | ij_java_finally_on_new_line = false
108 | ij_java_for_brace_force = never
109 | ij_java_for_statement_new_line_after_left_paren = false
110 | ij_java_for_statement_right_paren_on_new_line = false
111 | ij_java_for_statement_wrap = normal
112 | ij_java_generate_final_locals = false
113 | ij_java_generate_final_parameters = false
114 | ij_java_if_brace_force = never
115 | ij_java_imports_layout = *, |, javax.**, java.**, |, $*
116 | ij_java_indent_case_from_switch = true
117 | ij_java_insert_inner_class_imports = false
118 | ij_java_insert_override_annotation = true
119 | ij_java_keep_blank_lines_before_right_brace = 2
120 | ij_java_keep_blank_lines_between_package_declaration_and_header = 2
121 | ij_java_keep_blank_lines_in_code = 2
122 | ij_java_keep_blank_lines_in_declarations = 2
123 | ij_java_keep_builder_methods_indents = false
124 | ij_java_keep_control_statement_in_one_line = true
125 | ij_java_keep_first_column_comment = true
126 | ij_java_keep_indents_on_empty_lines = false
127 | ij_java_keep_line_breaks = true
128 | ij_java_keep_multiple_expressions_in_one_line = false
129 | ij_java_keep_simple_blocks_in_one_line = false
130 | ij_java_keep_simple_classes_in_one_line = false
131 | ij_java_keep_simple_lambdas_in_one_line = false
132 | ij_java_keep_simple_methods_in_one_line = false
133 | ij_java_label_indent_absolute = false
134 | ij_java_label_indent_size = 0
135 | ij_java_lambda_brace_style = end_of_line
136 | ij_java_layout_static_imports_separately = true
137 | ij_java_line_comment_add_space = false
138 | ij_java_line_comment_at_first_column = true
139 | ij_java_method_annotation_wrap = split_into_lines
140 | ij_java_method_brace_style = end_of_line
141 | ij_java_method_call_chain_wrap = normal
142 | ij_java_method_parameters_new_line_after_left_paren = false
143 | ij_java_method_parameters_right_paren_on_new_line = false
144 | ij_java_method_parameters_wrap = normal
145 | ij_java_modifier_list_wrap = false
146 | ij_java_names_count_to_use_import_on_demand = 999
147 | ij_java_new_line_after_lparen_in_record_header = false
148 | ij_java_parameter_annotation_wrap = normal
149 | ij_java_parentheses_expression_new_line_after_left_paren = false
150 | ij_java_parentheses_expression_right_paren_on_new_line = false
151 | ij_java_place_assignment_sign_on_next_line = false
152 | ij_java_prefer_longer_names = true
153 | ij_java_prefer_parameters_wrap = false
154 | ij_java_record_components_wrap = normal
155 | ij_java_repeat_synchronized = true
156 | ij_java_replace_instanceof_and_cast = false
157 | ij_java_replace_null_check = true
158 | ij_java_replace_sum_lambda_with_method_ref = true
159 | ij_java_resource_list_new_line_after_left_paren = false
160 | ij_java_resource_list_right_paren_on_new_line = false
161 | ij_java_resource_list_wrap = normal
162 | ij_java_rparen_on_new_line_in_record_header = false
163 | ij_java_space_after_closing_angle_bracket_in_type_argument = false
164 | ij_java_space_after_colon = true
165 | ij_java_space_after_comma = true
166 | ij_java_space_after_comma_in_type_arguments = true
167 | ij_java_space_after_for_semicolon = true
168 | ij_java_space_after_quest = true
169 | ij_java_space_after_type_cast = true
170 | ij_java_space_before_annotation_array_initializer_left_brace = false
171 | ij_java_space_before_annotation_parameter_list = false
172 | ij_java_space_before_array_initializer_left_brace = true
173 | ij_java_space_before_catch_keyword = true
174 | ij_java_space_before_catch_left_brace = true
175 | ij_java_space_before_catch_parentheses = true
176 | ij_java_space_before_class_left_brace = true
177 | ij_java_space_before_colon = true
178 | ij_java_space_before_colon_in_foreach = true
179 | ij_java_space_before_comma = false
180 | ij_java_space_before_do_left_brace = true
181 | ij_java_space_before_else_keyword = true
182 | ij_java_space_before_else_left_brace = true
183 | ij_java_space_before_finally_keyword = true
184 | ij_java_space_before_finally_left_brace = true
185 | ij_java_space_before_for_left_brace = true
186 | ij_java_space_before_for_parentheses = true
187 | ij_java_space_before_for_semicolon = false
188 | ij_java_space_before_if_left_brace = true
189 | ij_java_space_before_if_parentheses = true
190 | ij_java_space_before_method_call_parentheses = false
191 | ij_java_space_before_method_left_brace = true
192 | ij_java_space_before_method_parentheses = false
193 | ij_java_space_before_opening_angle_bracket_in_type_parameter = false
194 | ij_java_space_before_quest = true
195 | ij_java_space_before_switch_left_brace = true
196 | ij_java_space_before_switch_parentheses = true
197 | ij_java_space_before_synchronized_left_brace = true
198 | ij_java_space_before_synchronized_parentheses = true
199 | ij_java_space_before_try_left_brace = true
200 | ij_java_space_before_try_parentheses = true
201 | ij_java_space_before_type_parameter_list = false
202 | ij_java_space_before_while_keyword = true
203 | ij_java_space_before_while_left_brace = true
204 | ij_java_space_before_while_parentheses = true
205 | ij_java_space_inside_one_line_enum_braces = false
206 | ij_java_space_within_empty_array_initializer_braces = false
207 | ij_java_space_within_empty_method_call_parentheses = false
208 | ij_java_space_within_empty_method_parentheses = false
209 | ij_java_spaces_around_additive_operators = true
210 | ij_java_spaces_around_assignment_operators = true
211 | ij_java_spaces_around_bitwise_operators = true
212 | ij_java_spaces_around_equality_operators = true
213 | ij_java_spaces_around_lambda_arrow = true
214 | ij_java_spaces_around_logical_operators = true
215 | ij_java_spaces_around_method_ref_dbl_colon = false
216 | ij_java_spaces_around_multiplicative_operators = true
217 | ij_java_spaces_around_relational_operators = true
218 | ij_java_spaces_around_shift_operators = true
219 | ij_java_spaces_around_type_bounds_in_type_parameters = true
220 | ij_java_spaces_around_unary_operator = false
221 | ij_java_spaces_within_angle_brackets = false
222 | ij_java_spaces_within_annotation_parentheses = false
223 | ij_java_spaces_within_array_initializer_braces = false
224 | ij_java_spaces_within_braces = false
225 | ij_java_spaces_within_brackets = false
226 | ij_java_spaces_within_cast_parentheses = false
227 | ij_java_spaces_within_catch_parentheses = false
228 | ij_java_spaces_within_for_parentheses = false
229 | ij_java_spaces_within_if_parentheses = false
230 | ij_java_spaces_within_method_call_parentheses = false
231 | ij_java_spaces_within_method_parentheses = false
232 | ij_java_spaces_within_parentheses = false
233 | ij_java_spaces_within_record_header = false
234 | ij_java_spaces_within_switch_parentheses = false
235 | ij_java_spaces_within_synchronized_parentheses = false
236 | ij_java_spaces_within_try_parentheses = false
237 | ij_java_spaces_within_while_parentheses = false
238 | ij_java_special_else_if_treatment = true
239 | ij_java_subclass_name_suffix = Impl
240 | ij_java_ternary_operation_signs_on_next_line = false
241 | ij_java_ternary_operation_wrap = normal
242 | ij_java_test_name_suffix = Test
243 | ij_java_throws_keyword_wrap = normal
244 | ij_java_throws_list_wrap = normal
245 | ij_java_use_external_annotations = false
246 | ij_java_use_fq_class_names = false
247 | ij_java_use_relative_indents = false
248 | ij_java_use_single_class_imports = true
249 | ij_java_variable_annotation_wrap = normal
250 | ij_java_visibility = public
251 | ij_java_while_brace_force = never
252 | ij_java_while_on_new_line = false
253 | ij_java_wrap_comments = false
254 | ij_java_wrap_first_method_in_call_chain = false
255 | ij_java_wrap_long_lines = false
256 |
257 | [*.properties]
258 | ij_properties_align_group_field_declarations = false
259 | ij_properties_keep_blank_lines = false
260 | ij_properties_key_value_delimiter = equals
261 | ij_properties_spaces_around_key_value_delimiter = false
262 |
263 | [.editorconfig]
264 | ij_editorconfig_align_group_field_declarations = false
265 | ij_editorconfig_space_after_colon = false
266 | ij_editorconfig_space_after_comma = true
267 | ij_editorconfig_space_before_colon = false
268 | ij_editorconfig_space_before_comma = false
269 | ij_editorconfig_spaces_around_assignment_operators = true
270 |
271 | [{*.ant,*.fxml,*.jhm,*.jnlp,*.jrxml,*.jspx,*.pom,*.rng,*.tagx,*.tld,*.wsdl,*.xml,*.xsd,*.xsl,*.xslt,*.xul}]
272 | ij_xml_align_attributes = true
273 | ij_xml_align_text = false
274 | ij_xml_attribute_wrap = normal
275 | ij_xml_block_comment_add_space = false
276 | ij_xml_block_comment_at_first_column = true
277 | ij_xml_keep_blank_lines = 2
278 | ij_xml_keep_indents_on_empty_lines = false
279 | ij_xml_keep_line_breaks = true
280 | ij_xml_keep_line_breaks_in_text = true
281 | ij_xml_keep_whitespaces = false
282 | ij_xml_keep_whitespaces_around_cdata = preserve
283 | ij_xml_keep_whitespaces_inside_cdata = false
284 | ij_xml_line_comment_at_first_column = true
285 | ij_xml_space_after_tag_name = false
286 | ij_xml_space_around_equals_in_attribute = false
287 | ij_xml_space_inside_empty_tag = false
288 | ij_xml_text_wrap = normal
289 | ij_xml_use_custom_settings = false
290 |
291 | [{*.bash,*.sh,*.zsh}]
292 | indent_size = 2
293 | tab_width = 2
294 | ij_shell_binary_ops_start_line = false
295 | ij_shell_keep_column_alignment_padding = false
296 | ij_shell_minify_program = false
297 | ij_shell_redirect_followed_by_space = false
298 | ij_shell_switch_cases_indented = false
299 | ij_shell_use_unix_line_separator = true
300 |
301 | [{*.har,*.json}]
302 | indent_size = 2
303 | ij_json_keep_blank_lines_in_code = 0
304 | ij_json_keep_indents_on_empty_lines = false
305 | ij_json_keep_line_breaks = true
306 | ij_json_space_after_colon = true
307 | ij_json_space_after_comma = true
308 | ij_json_space_before_colon = true
309 | ij_json_space_before_comma = false
310 | ij_json_spaces_within_braces = false
311 | ij_json_spaces_within_brackets = false
312 | ij_json_wrap_long_lines = false
313 |
314 | [{*.markdown,*.md}]
315 | ij_markdown_force_one_space_after_blockquote_symbol = true
316 | ij_markdown_force_one_space_after_header_symbol = true
317 | ij_markdown_force_one_space_after_list_bullet = true
318 | ij_markdown_force_one_space_between_words = true
319 | ij_markdown_keep_indents_on_empty_lines = false
320 | ij_markdown_max_lines_around_block_elements = 1
321 | ij_markdown_max_lines_around_header = 1
322 | ij_markdown_max_lines_between_paragraphs = 1
323 | ij_markdown_min_lines_around_block_elements = 1
324 | ij_markdown_min_lines_around_header = 1
325 | ij_markdown_min_lines_between_paragraphs = 1
326 |
327 | [{*.yaml,*.yml}]
328 | indent_size = 2
329 | ij_yaml_align_values_properties = do_not_align
330 | ij_yaml_autoinsert_sequence_marker = true
331 | ij_yaml_block_mapping_on_new_line = false
332 | ij_yaml_indent_sequence_value = true
333 | ij_yaml_keep_indents_on_empty_lines = false
334 | ij_yaml_keep_line_breaks = true
335 | ij_yaml_sequence_on_new_line = false
336 | ij_yaml_space_before_colon = false
337 | ij_yaml_spaces_within_braces = true
338 | ij_yaml_spaces_within_brackets = true
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | extent-test-report
3 | target
4 | test-output
5 |
6 | # LOG FILE
7 | logs
8 |
--------------------------------------------------------------------------------
/DockerFile:
--------------------------------------------------------------------------------
1 | FROM maven:3.6.3-jdk-8
2 | COPY extent-test-report/index.html home/apiframework/index.html
3 | COPY pom.xml home/apiframework/pom.xml
4 | COPY testng.xml home/apiframework/testng.xml
5 | WORKDIR home/apiframework
6 | ENTRYPOINT mvn clean test
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # REST ASSURED - API automation framework
2 |
3 | 1) Java library (API) for testing RESTful web services.
4 | 2) Used to test XML and JSON based web services.
5 | 3) Supports GET, POST, PATCH, PUT, DELETE, HEAD, OPTIONS. Can be integrated with testing frameworks like JUnit, TestNG.
6 | 4) Rest Assured is implement in Groovy. It uses Groovy under the hood to fetch the JSON object (GPath Expression)
7 |
8 | REST:
9 |
10 | - Representation State Transfer is an architectural style sending the representational state of an object at that
11 | particular time. - Rest API is Stateless (i.e., Server will not store any information about the client)
12 | JSON:
13 | - Key value pair where key is always a String and Value can be String, number, boolean, JSON Object, JSON Array, null
14 | etc., - {} --> JSON Object - [] --> JSON Array
15 |
16 | Path Param - Used to identify specific resource, it is mandatory. Query Param - Used to Sort/filter the resources, it is
17 | optional.
18 |
19 | ### Quick Start
20 |
21 | - Java
22 | - IntelliJ IDE
23 | - Maven
24 | - TestNG
25 |
26 | ### Create a local REST API with JSON Server for testing
27 |
28 | JSON Server: Used to create our own fake Rest API.
29 |
30 | 1) Installing JSON Server
31 |
32 | ```
33 | npm install -g json-server
34 | ```
35 |
36 | 2) Start JSON Server
37 |
38 | ```
39 | json-server --watch db.json
40 | ```
41 |
42 | REFERENCE LINK:
43 | https://medium.com/codingthesmartway-com-blog/create-a-rest-api-with-json-server-36da8680136d
44 |
45 | 3) Created API will be available in the local server
46 |
47 | ```
48 | http://localhost:3000/
49 | ```
50 |
51 | To start Json Server on the machine IP address
52 |
53 | ```
54 | json-server --host <> --watch db.json
55 | ```
56 |
57 | ### Demo Uri's
58 |
59 | ```
60 | https://reqres.in/
61 | http://ergast.com/mrd/
62 | ```
63 |
64 | ### Validate JSON Schema
65 |
66 | 1) Create or Get JSON Schema
67 | 2) Add JSON Schema file in src/test/resources path
68 | 3) Add maven dependency for JSON Schema validator
69 |
70 | ### Validate XML Schema
71 |
72 | 1) Create or Get XML Schema (XSD)
73 | 2) Add XSD in src/test/resources path
74 |
75 | ### Authorization
76 |
77 | Authorization gives the users permission to access a resource.
78 |
79 | ### Authentication
80 |
81 | Process to prove that you are valid user or not Supports several authentication schemes - OAuth, digest, certificate,
82 | form and preemptive basic authentication. Basic authentication:
83 |
84 | - Preemptive : Will supply the credentials as header before the server response. - Challanged : Will not supply
85 | credentials until the server asks for it.
86 |
87 | ### OAuth
88 |
89 | - Open Standard for authorization protocol.
90 |
91 | Dependency:
92 |
93 | ```
94 | - Rest Assured
95 | - ScribeJava-APIs
96 | - Developer Account
97 | ```
98 |
99 | NOTE: Developer account is mandatory to work with OAuth authentication.
100 |
101 | ### Cookie based Authentication
102 |
103 | - An HTTP cookie (Web cookie, browser cookie) is a small piece of data that a server sends to the user's web browser.
104 | Example: Keeping a user logged in.
105 | - Uses HTTP cookies to authenticate client requests and maintain session information.
106 | - JSESSIONID is a cookie in J2EE web application which is used in session tracking.
107 |
108 | ### WIREMOCK - Running as standalone process
109 |
110 | - WireMock is a library for stubbing and mocking web services.
111 | - It constructs an HTTP server that we could connect to as we would to an actual web service.
112 | - When a WireMock server is in action, we can set up expectations, call the service, and then verify its behaviors.
113 | - The WireMock server can be run in its own process, and configured via the Java API, JSON over HTTP or JSON files.
114 | - Running it through Maven/gradle will start the mock service once the test start running and stops after test completes.
115 |
116 | Once you have downloaded the standalone JAR you can run it simply by doing this
117 |
118 | ```
119 | java -jar wiremock-jre8-standalone-2.33.1.jar
120 | ```
121 |
122 | ### Command line options
123 |
124 | `--port`: Set the HTTP port number e.g. java -jar wiremock-jre8-standalone-2.33.1.jar --port 9091
125 |
126 | `--https-port`: If specified, enables HTTPS on the supplied port. Note: When you specify this parameter, WireMock will
127 | still, additionally, bind to an HTTP port (8080 by default). So when running multiple WireMock servers you will also
128 | need to specify the --port parameter in order to avoid conflicts.
129 |
130 | ### Different ways of constructing POST request
131 |
132 | 1. As String
133 | 2. From external file (.json file)
134 | 3. Read it as String from external file (.json file) and replace values.
135 | 4. Using HashMap (for Json Object {} ) and ArrayList (for Json Array []).
136 | 5. Using external Json library (JSONObject, JSONArray).
137 |
138 | ### Test Application
139 |
140 | Swagger Doc
141 |
142 | ```
143 | https://jobportalkarate.herokuapp.com/swagger-ui.html
144 | ```
145 |
146 | To access the application locally - Open terminal, navigate to the location of 'jobportal-0.0.1-SNAPSHOT' JAR file and
147 | execute the following command
148 |
149 | ```
150 | java -jar -Dserver.port=5050 jobportal-0.0.1-SNAPSHOT.jar
151 | ```
152 |
153 | This will start the server and the following url can be used to access the Swagger doc
154 |
155 | ```
156 | http://localhost:5050/swagger-ui.html
157 | ```
158 |
159 | ### Build Docker Image
160 |
161 | ```
162 | docker build -t : .
163 | ```
164 |
165 | ### Create docker image on top of a container (Base image)
166 |
167 | ```
168 | docker commit <>
169 | docker tag <> <>
170 | docker build -t <>
171 | ```
172 |
173 | ### Push image to docker hub
174 |
175 | ```
176 | docker login
177 | docker push <>
178 | ```
179 |
--------------------------------------------------------------------------------
/checkstyle/checkstyle-suppressions.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/checkstyle/checkstyle.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/db.json:
--------------------------------------------------------------------------------
1 | {
2 | "employees": [
3 | {
4 | "id": 1,
5 | "first_name": "Sebastian",
6 | "last_name": "Eschweiler",
7 | "email": "sebastian@codingthesmartway.com"
8 | },
9 | {
10 | "id": 2,
11 | "first_name": "Steve",
12 | "last_name": "Palmer",
13 | "email": "steve@codingthesmartway.com"
14 | },
15 | {
16 | "id": 3,
17 | "first_name": "Ann",
18 | "last_name": "Smith",
19 | "email": "ann@codingthesmartway.com"
20 | },
21 | {
22 | "id": 5,
23 | "first_name": "Auto",
24 | "last_name": "user",
25 | "email": "abc@testmail.com"
26 | },
27 | {
28 | "id": 6,
29 | "first_name": "Test",
30 | "last_name": "User",
31 | "email": "test@email.com"
32 | },
33 | {
34 | "id": 18,
35 | "first_name": "Test",
36 | "last_name": "User",
37 | "email": "test@email.com"
38 | },
39 | {
40 | "id": 15,
41 | "first_name": "auto",
42 | "last_name": "test_user",
43 | "email": "test_user@email.com",
44 | "jobs": [
45 | "Dev",
46 | "Tester"
47 | ],
48 | "skill": {
49 | "programming": "java",
50 | "automation": [
51 | "web, mobile, api"
52 | ]
53 | }
54 | },
55 | {
56 | "jobs": [
57 | "Tester",
58 | "Dev"
59 | ],
60 | "skill": {
61 | "automation": [
62 | "web, mobile, api"
63 | ],
64 | "programming": "java"
65 | },
66 | "last_name": "test_user",
67 | "id": 44,
68 | "first_name": "auto",
69 | "email": "test_user@email.com"
70 | },
71 | {
72 | "jobs": [
73 | "Tester",
74 | "Dev"
75 | ],
76 | "skill": {
77 | "automation": [
78 | "web, mobile, api"
79 | ],
80 | "programming": "java"
81 | },
82 | "last_name": "test_user",
83 | "id": 35,
84 | "first_name": "auto",
85 | "email": "test_user@email.com"
86 | },
87 | {
88 | "jobs": [
89 | "Tester",
90 | "Dev"
91 | ],
92 | "skill": {
93 | "automation": [
94 | "web, mobile, api"
95 | ],
96 | "programming": "java"
97 | },
98 | "last_name": "test_user",
99 | "id": 24,
100 | "first_name": "auto",
101 | "email": [
102 | "test_user@email.com",
103 | "test_user2@email.com"
104 | ]
105 | },
106 | {
107 | "id": 43,
108 | "first_name": "auto",
109 | "last_name": "test_user",
110 | "email": "test_user@email.com",
111 | "jobs": [
112 | "Dev",
113 | "Tester"
114 | ],
115 | "skill": {
116 | "programming": "java",
117 | "automation": [
118 | "web, mobile, api"
119 | ]
120 | }
121 | },
122 | {
123 | "id": 12,
124 | "firstName": "fname",
125 | "lastName": "lname",
126 | "email": "testmail@test.com",
127 | "jobs": [],
128 | "skill": null
129 | },
130 | {
131 | "last_name": "lastname",
132 | "first_name": "firstname",
133 | "id": 13
134 | },
135 | {
136 | "firstName": "fname",
137 | "id": 14,
138 | "jobs": [
139 | "QA",
140 | "SDET"
141 | ],
142 | "lastName": "lname",
143 | "skill": {
144 | "programming": "core java",
145 | "automation": [
146 | "rest-assured",
147 | "jackson"
148 | ]
149 | }
150 | },
151 | {
152 | "firstName": "fname",
153 | "id": 22,
154 | "jobs": [
155 | "QA",
156 | "SDET"
157 | ],
158 | "lastName": "lname",
159 | "skill": {
160 | "programming": "core java",
161 | "automation": [
162 | "rest-assured",
163 | "jackson"
164 | ]
165 | }
166 | }
167 | ]
168 | }
--------------------------------------------------------------------------------
/jobportal-0.0.1-SNAPSHOT.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Thangarajtk/restassured-api-automation/2cebc419f761c26743a664a5ed30178c82dcd245/jobportal-0.0.1-SNAPSHOT.jar
--------------------------------------------------------------------------------
/lombok.config:
--------------------------------------------------------------------------------
1 | lombok.addLombokGeneratedAnnotation = true
2 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
4 | 4.0.0
5 | RestAssured
6 | API_Automation
7 | 0.0.1-SNAPSHOT
8 |
9 |
10 | UTF-8
11 | 11
12 | 11
13 | 3.8.1
14 | 3.0.0-M5
15 | 3.5.0
16 | 7.10.2
17 | 5.4.0
18 | 5.1.2
19 | 5.3.0
20 | 1.1.1
21 | 1.0.12
22 | 1.18.34
23 | 1.4.9
24 | 2.16.1
25 | 3.0.1
26 | 2.10
27 | 2.17.0
28 | 3.26.3
29 | 1.0.2
30 | 8.3.3
31 | 2.23.1
32 | 4.5.0
33 | 1.1.0
34 | 10.14.1
35 | checkstyle/checkstyle.xml
36 | checkstyle/checkstyle-suppressions.xml
37 |
38 |
39 |
40 |
41 |
42 | org.codehaus.groovy
43 | groovy
44 | 3.0.22
45 |
46 |
47 |
48 |
49 | io.rest-assured
50 | rest-assured
51 | ${restassured.version}
52 |
53 |
54 |
55 |
57 |
58 | io.rest-assured
59 | json-path
60 | ${restassured.version}
61 |
62 |
63 |
65 |
66 | io.rest-assured
67 | xml-path
68 | ${restassured.version}
69 |
70 |
71 |
72 | io.rest-assured
73 | rest-assured-common
74 | ${restassured.version}
75 |
76 |
77 |
78 |
79 | io.rest-assured
80 | json-schema-validator
81 | ${restassured.version}
82 |
83 |
84 |
85 |
86 | org.testng
87 | testng
88 | ${testng.version}
89 |
90 |
91 |
92 |
93 | com.googlecode.json-simple
94 | json-simple
95 | ${json-simple.version}
96 |
97 |
98 |
99 |
100 | com.aventstack
101 | extentreports
102 | ${extentreports.version}
103 |
104 |
105 |
106 |
107 | org.apache.poi
108 | poi
109 | ${apache-poi.version}
110 |
111 |
112 |
113 |
114 | org.apache.poi
115 | poi-ooxml
116 | ${apache-poi.version}
117 |
118 |
119 |
120 |
121 | commons-io
122 | commons-io
123 | ${commons-io.version}
124 |
125 |
126 |
127 |
128 | com.mashape.unirest
129 | unirest-java
130 | ${unirest-java.version}
131 |
132 |
133 |
134 |
135 | com.google.code.gson
136 | gson
137 | ${gson.version}
138 |
139 |
140 |
141 | com.github.scribejava
142 | scribejava-apis
143 | ${scribejava-apis.version}
144 | test
145 |
146 |
147 |
148 | com.github.tomakehurst
149 | wiremock-jre8-standalone
150 | ${wiremock-jre8-standalone.version}
151 | test
152 |
153 |
154 |
155 | org.aeonbits.owner
156 | owner
157 | ${owner.version}
158 |
159 |
160 |
161 |
162 | org.projectlombok
163 | lombok
164 | ${lombok.version}
165 | provided
166 |
167 |
168 |
169 |
170 | com.fasterxml.jackson.core
171 | jackson-databind
172 | ${jackson-databind.version}
173 |
174 |
175 |
176 |
177 | com.github.javafaker
178 | javafaker
179 | ${javafaker.version}
180 |
181 |
182 |
183 |
184 | org.assertj
185 | assertj-core
186 | ${assertj.version}
187 | test
188 |
189 |
190 |
191 | org.apache.maven.plugins
192 | maven-checkstyle-plugin
193 | ${maven-checkstyle-plugin.version}
194 |
195 |
196 |
197 | org.duraspace
198 | codestyle
199 | ${codestyle.version}
200 |
201 |
202 |
203 | com.puppycrawl.tools
204 | checkstyle
205 | ${checkstyle.version}
206 |
207 |
208 |
209 | uk.co.jemos.podam
210 | podam
211 | 8.0.2.RELEASE
212 | test
213 |
214 |
215 |
216 |
217 | org.apache.logging.log4j
218 | log4j-core
219 | ${log4j.version}
220 |
221 |
222 |
223 |
224 | org.apache.logging.log4j
225 | log4j-api
226 | ${log4j.version}
227 |
228 |
229 |
230 |
231 | com.github.ozlerhakan
232 | poiji
233 | ${poiji.version}
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 | org.apache.maven.plugins
243 | maven-compiler-plugin
244 | ${maven-compiler-plugin.version}
245 |
246 | 11
247 | 11
248 |
249 |
250 |
251 |
252 | org.apache.maven.plugins
253 | maven-surefire-plugin
254 | ${maven-surefire-plugin.version}
255 |
256 |
257 | testng.xml
258 |
259 |
260 |
261 |
262 |
263 | org.apache.maven.plugins
264 | maven-checkstyle-plugin
265 | ${maven-checkstyle-plugin.version}
266 |
267 |
268 | verify-style
269 | verify
270 |
271 | check
272 |
273 |
274 |
275 |
276 | ${checkstyle.config}
277 | ${checkstyle.suppress}
278 | UTF-8
279 | UTF-8
280 | true
281 | true
282 | true
283 | true
284 |
285 |
286 |
287 |
288 |
289 |
290 | maven_central
291 | Maven Central
292 | https://repo.maven.apache.org/maven2/
293 |
294 |
295 |
296 |
--------------------------------------------------------------------------------
/src/main/java/com/automation/annotations/FrameworkAnnotation.java:
--------------------------------------------------------------------------------
1 | package com.automation.annotations;
2 |
3 | import com.automation.enums.Authors;
4 | import com.automation.enums.CategoryType;
5 |
6 | import java.lang.annotation.Documented;
7 | import java.lang.annotation.Retention;
8 | import java.lang.annotation.Target;
9 |
10 | import static java.lang.annotation.ElementType.METHOD;
11 | import static java.lang.annotation.RetentionPolicy.RUNTIME;
12 |
13 | @Retention(RUNTIME)
14 | @Target(METHOD)
15 | @Documented
16 | public @interface FrameworkAnnotation {
17 |
18 | Authors[] author();
19 |
20 | CategoryType[] category();
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/automation/config/ConfigFactory.java:
--------------------------------------------------------------------------------
1 | package com.automation.config;
2 |
3 | import lombok.AccessLevel;
4 | import lombok.NoArgsConstructor;
5 | import org.aeonbits.owner.ConfigCache;
6 |
7 | @NoArgsConstructor(access = AccessLevel.PRIVATE)
8 | public class ConfigFactory {
9 |
10 | public static FrameworkConfig getConfig() {
11 | return ConfigCache.getOrCreate(FrameworkConfig.class);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/automation/config/FrameworkConfig.java:
--------------------------------------------------------------------------------
1 | package com.automation.config;
2 |
3 | import org.aeonbits.owner.Config;
4 |
5 | @Config.LoadPolicy(Config.LoadType.MERGE)
6 | @Config.Sources({
7 | "system:properties",
8 | "system:env",
9 | "file:${user.dir}/src/test/resources/config/config.properties"})
10 | public interface FrameworkConfig extends Config {
11 |
12 | String override_reports();
13 |
14 | boolean retry_failed_tests();
15 |
16 | int retry_count();
17 |
18 | String base_uri();
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/com/automation/constants/FCWithSingleton.java:
--------------------------------------------------------------------------------
1 | package com.automation.constants;
2 |
3 | import lombok.AccessLevel;
4 | import lombok.NoArgsConstructor;
5 |
6 | @NoArgsConstructor(access = AccessLevel.PRIVATE)
7 | public final class FCWithSingleton {
8 |
9 | // Singleton design pattern - Single instance for a class at a particular point of time
10 | // It is part of creation design pattern
11 | private static FCWithSingleton INSTANCE = null;
12 |
13 | private static synchronized FCWithSingleton getInstance() { // To make it Thread-Safe
14 | if (INSTANCE == null) {
15 | INSTANCE = new FCWithSingleton();
16 | }
17 | return INSTANCE;
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/automation/constants/FrameworkConstants.java:
--------------------------------------------------------------------------------
1 | package com.automation.constants;
2 |
3 | import com.automation.config.ConfigFactory;
4 | import lombok.AccessLevel;
5 | import lombok.NoArgsConstructor;
6 |
7 | import java.io.File;
8 | import java.time.LocalDateTime;
9 | import java.time.format.DateTimeFormatter;
10 |
11 | @NoArgsConstructor(access = AccessLevel.PRIVATE)
12 | public final class FrameworkConstants {
13 |
14 | private static final String PROJECT_PATH = System.getProperty("user.dir");
15 | public static final String RESOURCES_FOLDER_PATH = PROJECT_PATH + File.separator + "src" + File.separator
16 | + "test" + File.separator + "resources";
17 | public static final String CONFIG_PROPERTIES_PATH = RESOURCES_FOLDER_PATH + File.separator + "config.properties";
18 | public static final String JSON_SCHEMA_PATH = RESOURCES_FOLDER_PATH + File.separator + "json" + File.separator + "json-schema.json";
19 | public static final String XML_XSD_SCHEMA_PATH =
20 | RESOURCES_FOLDER_PATH + File.separator + "xml" + File.separator + "xml-xsd-schema.xsd";
21 | public static final String XML_DTD_SCHEMA_PATH =
22 | RESOURCES_FOLDER_PATH + File.separator + "xml" + File.separator + "xml-dtd-schema.dtd";
23 |
24 | private static final String extentReportPath = PROJECT_PATH + File.separator + "extent-test-report";
25 |
26 | public static String getExtentReportPath() {
27 | return ConfigFactory.getConfig().override_reports().equalsIgnoreCase("yes") ?
28 | extentReportPath + File.separator + "index.html" :
29 | extentReportPath + File.separator + getCurrentDateTime() + File.separator + "index.html";
30 | }
31 |
32 | private static String getCurrentDateTime() {
33 | DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy_MM_dd-HH_mm_ss");
34 | return dateTimeFormatter.format(LocalDateTime.now());
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/automation/enums/Authors.java:
--------------------------------------------------------------------------------
1 | package com.automation.enums;
2 |
3 | public enum Authors {
4 |
5 | USER_1, USER_2
6 | }
7 |
--------------------------------------------------------------------------------
/src/main/java/com/automation/enums/CategoryType.java:
--------------------------------------------------------------------------------
1 | package com.automation.enums;
2 |
3 |
4 | public enum CategoryType {
5 |
6 | REGRESSION,
7 | SMOKE,
8 | SANITY
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/java/com/automation/enums/ConfigProperties.java:
--------------------------------------------------------------------------------
1 | package com.automation.enums;
2 |
3 | public enum ConfigProperties {
4 | OVERRIDE_REPORTS,
5 | RETRY_FAILED_TESTS,
6 | RETRY_COUNT
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/java/com/automation/exceptions/FrameworkException.java:
--------------------------------------------------------------------------------
1 | package com.automation.exceptions;
2 |
3 | public class FrameworkException extends RuntimeException {
4 |
5 | /**
6 | * Pass the message that needs to be appended to the stacktrace
7 | *
8 | * @param message Details about the exception or custom message
9 | */
10 | public FrameworkException(String message) {
11 | super(message);
12 | }
13 |
14 | /**
15 | * @param message Details about the exception or custom message
16 | * @param cause Pass the enriched stacktrace or customised stacktrace
17 | */
18 | public FrameworkException(String message, Throwable cause) {
19 | super(message, cause);
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/com/automation/exceptions/ReportInitializationException.java:
--------------------------------------------------------------------------------
1 | package com.automation.exceptions;
2 |
3 | public class ReportInitializationException extends FrameworkException {
4 |
5 | /**
6 | * Pass the message that needs to be appended to the stacktrace
7 | *
8 | * @param message Details about the exception or custom message
9 | */
10 | public ReportInitializationException(String message) {
11 | super(message);
12 | }
13 |
14 | /**
15 | * @param message Details about the exception or custom message
16 | * @param cause Pass the enriched stacktrace or customised stacktrace
17 | */
18 | public ReportInitializationException(String message, Throwable cause) {
19 | super(message, cause);
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/com/automation/listeners/Listeners.java:
--------------------------------------------------------------------------------
1 | package com.automation.listeners;
2 |
3 | import com.automation.annotations.FrameworkAnnotation;
4 | import com.automation.reports.ExtentLogger;
5 | import com.automation.reports.ExtentReport;
6 | import org.testng.ISuite;
7 | import org.testng.ISuiteListener;
8 | import org.testng.ITestListener;
9 | import org.testng.ITestResult;
10 |
11 | public class Listeners implements ITestListener, ISuiteListener {
12 |
13 | private static final String MESSAGE = "Test - ";
14 |
15 | @Override
16 | public void onStart(ISuite suite) {
17 | ExtentReport.initExtentReport();
18 | }
19 |
20 | @Override
21 | public void onFinish(ISuite suite) {
22 | ExtentReport.flushExtentReport();
23 | }
24 |
25 | @Override
26 | public void onTestStart(ITestResult result) {
27 | ExtentReport.createTest(result.getMethod().getMethodName());
28 | ExtentLogger.addAuthors(result.getMethod().getConstructorOrMethod().getMethod().getAnnotation(FrameworkAnnotation.class)
29 | .author());
30 | ExtentLogger.addCategories(result.getMethod().getConstructorOrMethod().getMethod().getAnnotation(FrameworkAnnotation.class)
31 | .category());
32 | ExtentLogger.pass(MESSAGE + result.getMethod().getMethodName() + " is started");
33 | }
34 |
35 | @Override
36 | public void onTestSuccess(ITestResult result) {
37 | ExtentLogger.pass(MESSAGE + result.getMethod().getMethodName() + " is passed");
38 | }
39 |
40 | @Override
41 | public void onTestFailure(ITestResult result) {
42 | ExtentLogger.logFailureDetails(MESSAGE + result.getMethod().getMethodName() + " is failed");
43 | }
44 |
45 | @Override
46 | public void onTestSkipped(ITestResult result) {
47 | ExtentLogger.skip(MESSAGE + result.getMethod().getMethodName() + " is skipped");
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/com/automation/listeners/RetryFailedTests.java:
--------------------------------------------------------------------------------
1 | package com.automation.listeners;
2 |
3 | import com.automation.config.ConfigFactory;
4 | import org.testng.IRetryAnalyzer;
5 | import org.testng.ITestResult;
6 |
7 | public class RetryFailedTests implements IRetryAnalyzer {
8 |
9 | private final int maxRetry = ConfigFactory.getConfig().retry_count();
10 | private int count = 0;
11 |
12 | @Override
13 | public boolean retry(ITestResult result) {
14 | boolean value = false;
15 | if (ConfigFactory.getConfig().retry_failed_tests()) {
16 | value = count < maxRetry;
17 | count++;
18 | }
19 | return value;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/automation/models/builders/RequestBuilder.java:
--------------------------------------------------------------------------------
1 | package com.automation.models.builders;
2 |
3 | import io.restassured.builder.RequestSpecBuilder;
4 | import io.restassured.filter.log.RequestLoggingFilter;
5 | import io.restassured.specification.RequestSpecification;
6 | import lombok.AccessLevel;
7 | import lombok.NoArgsConstructor;
8 | import org.apache.commons.io.output.WriterOutputStream;
9 |
10 | import java.io.PrintStream;
11 | import java.io.StringWriter;
12 | import java.nio.charset.StandardCharsets;
13 |
14 | import static com.automation.config.ConfigFactory.getConfig;
15 | import static io.restassured.RestAssured.given;
16 | import static io.restassured.filter.log.LogDetail.ALL;
17 |
18 | @NoArgsConstructor(access = AccessLevel.PRIVATE)
19 | public final class RequestBuilder {
20 |
21 | /**
22 | * RequestSpecification is an Interface and RequestSpecBuilder is a class
23 | *
24 | * @return
25 | */
26 | public static RequestSpecification createRequestSpecification() {
27 | PrintStream printStream = new PrintStream(new WriterOutputStream(new StringWriter(), StandardCharsets.UTF_8), true);
28 |
29 | return new RequestSpecBuilder()
30 | .setBaseUri(getConfig().base_uri())
31 | .addFilter(new RequestLoggingFilter(printStream))
32 | .log(ALL)
33 | .build();
34 | }
35 |
36 | public static RequestSpecification buildRequest() {
37 | return given().baseUri("http://localhost:3000")
38 | .header("Content-Type", "application/json");
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/com/automation/models/builders/ResponseBuilder.java:
--------------------------------------------------------------------------------
1 | package com.automation.models.builders;
2 |
3 | import io.restassured.builder.ResponseSpecBuilder;
4 | import io.restassured.http.ContentType;
5 | import io.restassured.specification.ResponseSpecification;
6 | import lombok.AccessLevel;
7 | import lombok.NoArgsConstructor;
8 |
9 | import static java.net.HttpURLConnection.HTTP_OK;
10 |
11 | @NoArgsConstructor(access = AccessLevel.PRIVATE)
12 | public final class ResponseBuilder {
13 |
14 | public static ResponseSpecification createResponseSpecification() {
15 | return new ResponseSpecBuilder().
16 | expectStatusCode(HTTP_OK).
17 | expectContentType(ContentType.JSON).build();
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/com/automation/models/pojo/Employee.java:
--------------------------------------------------------------------------------
1 | package com.automation.models.pojo;
2 |
3 | import com.fasterxml.jackson.annotation.JsonInclude;
4 | import com.fasterxml.jackson.annotation.JsonPropertyOrder;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Builder;
7 | import lombok.Getter;
8 | import lombok.Setter;
9 |
10 | import java.util.List;
11 |
12 | @Getter
13 | @Setter
14 | @AllArgsConstructor
15 | @JsonInclude(value = JsonInclude.Include.NON_NULL) // Ignore fields with null value
16 | @JsonPropertyOrder(alphabetic = true) // To alphabetically order the JSON
17 | //@JsonIgnoreProperties(value = {"email"}) // To ignore the specified value
18 | @Builder
19 | public class Employee {
20 |
21 | private Integer id;
22 | private String firstname;
23 | private String lastname;
24 | private String email;
25 | private List jobs;
26 | private Skill skill;
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/com/automation/models/pojo/Skill.java:
--------------------------------------------------------------------------------
1 | package com.automation.models.pojo;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Getter;
5 | import lombok.Setter;
6 |
7 | import java.util.List;
8 |
9 | @Getter
10 | @Setter
11 | @AllArgsConstructor
12 | public class Skill {
13 |
14 | private String programming;
15 | private List automation;
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/com/automation/models/pojo/Student.java:
--------------------------------------------------------------------------------
1 | package com.automation.models.pojo;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Getter;
6 | import lombok.ToString;
7 |
8 | @Getter // This is required for Serialization and DeSerialization
9 | @AllArgsConstructor
10 | @ToString
11 | @Builder
12 | public class Student {
13 |
14 | private int id;
15 | private String firstname;
16 | private String lastname;
17 | private String email;
18 |
19 | // Static Inner class
20 | public static class StudentBuilderInnerClass {
21 | private int id;
22 | private String firstname;
23 | private String lastname;
24 | private String email;
25 |
26 | public static StudentBuilderInnerClass builder() {
27 | return new StudentBuilderInnerClass();
28 | }
29 |
30 | public StudentBuilderInnerClass setId(int id) {
31 | this.id = id;
32 | return this;
33 | }
34 |
35 | public StudentBuilderInnerClass setFirstname(String firstname) {
36 | this.firstname = firstname;
37 | return this;
38 | }
39 |
40 | public StudentBuilderInnerClass setLastname(String lastname) {
41 | this.lastname = lastname;
42 | return this;
43 | }
44 |
45 | public StudentBuilderInnerClass setEmail(String email) {
46 | this.email = email;
47 | return this;
48 | }
49 |
50 | public Student build() {
51 | return new Student(this.id, this.firstname, this.lastname, this.email);
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/com/automation/models/pojo/StudentBuilder.java:
--------------------------------------------------------------------------------
1 | package com.automation.models.pojo;
2 |
3 | import lombok.AccessLevel;
4 | import lombok.NoArgsConstructor;
5 |
6 | @NoArgsConstructor(access = AccessLevel.PRIVATE)
7 | public class StudentBuilder {
8 |
9 | private int id;
10 | private String firstname;
11 | private String lastname;
12 | private String email;
13 |
14 | public static StudentBuilder builder() {
15 | return new StudentBuilder();
16 | }
17 |
18 | public StudentBuilder setId(int id) {
19 | this.id = id;
20 | return this;
21 | }
22 |
23 | public StudentBuilder setFirstname(String firstname) {
24 | this.firstname = firstname;
25 | return this;
26 | }
27 |
28 | public StudentBuilder setLastname(String lastname) {
29 | this.lastname = lastname;
30 | return this;
31 | }
32 |
33 | public StudentBuilder setEmail(String email) {
34 | this.email = email;
35 | return this;
36 | }
37 |
38 | public Student build() {
39 | return new Student(this.id, this.firstname, this.lastname, this.email);
40 | }
41 | }
42 |
43 |
--------------------------------------------------------------------------------
/src/main/java/com/automation/reports/ExtentLogger.java:
--------------------------------------------------------------------------------
1 | package com.automation.reports;
2 |
3 | import com.automation.enums.Authors;
4 | import com.automation.enums.CategoryType;
5 | import com.aventstack.extentreports.Status;
6 | import com.aventstack.extentreports.markuputils.CodeLanguage;
7 | import com.aventstack.extentreports.markuputils.ExtentColor;
8 | import com.aventstack.extentreports.markuputils.Markup;
9 | import com.aventstack.extentreports.markuputils.MarkupHelper;
10 | import io.restassured.http.Header;
11 | import io.restassured.specification.QueryableRequestSpecification;
12 | import io.restassured.specification.RequestSpecification;
13 | import io.restassured.specification.SpecificationQuerier;
14 | import lombok.AccessLevel;
15 | import lombok.NoArgsConstructor;
16 |
17 | import java.util.List;
18 |
19 | @NoArgsConstructor(access = AccessLevel.PRIVATE)
20 | public final class ExtentLogger {
21 |
22 | public static void pass(String message) {
23 | ExtentManager.getExtentTest().pass(MarkupHelper.createLabel(message, ExtentColor.GREEN));
24 | }
25 |
26 | public static void logFailureDetails(String message) {
27 | ExtentManager.getExtentTest().fail(message);
28 | }
29 |
30 | public static void skip(String message) {
31 | ExtentManager.getExtentTest().skip(message);
32 | }
33 |
34 | public static void logInfo(Markup markup) {
35 | ExtentManager.getExtentTest().log(Status.INFO, markup);
36 | }
37 |
38 | // Overloaded method
39 | public static void logInfo(String message) {
40 | ExtentManager.getExtentTest().info(message);
41 | }
42 |
43 | public static void logResponse(String response) {
44 | ExtentManager.getExtentTest().pass(MarkupHelper.createCodeBlock(response, CodeLanguage.JSON));
45 | }
46 |
47 | public static void logRequest(RequestSpecification requestSpecification) {
48 | QueryableRequestSpecification query = SpecificationQuerier.query(requestSpecification);
49 | ExtentManager.getExtentTest().pass(MarkupHelper.createCodeBlock(String.valueOf(query.getBody()),
50 | CodeLanguage.JSON));
51 | for (Header header : query.getHeaders()) {
52 | logInfo(header.getName() + ":" + header.getValue());
53 | }
54 | }
55 |
56 | public static void logRequestInReport(String request) {
57 | logInfo(MarkupHelper.createLabel("API REQUEST", ExtentColor.ORANGE));
58 | logInfo(MarkupHelper.createCodeBlock(request));
59 | }
60 |
61 | public static void logResponseInReport(String label, String response) {
62 | logInfo(MarkupHelper.createLabel(label, ExtentColor.ORANGE));
63 | logInfo(MarkupHelper.createCodeBlock(response));
64 | }
65 |
66 | public static void logHeaders(List headerList) {
67 | String[][] headers = headerList.stream().map(header -> new String[] {header.getName(), header.getValue()})
68 | .toArray(String[][] :: new);
69 | ExtentManager.getExtentTest().info(MarkupHelper.createTable(headers));
70 | }
71 |
72 | public static void addAuthors(Authors[] authors) {
73 | for (Authors author : authors) {
74 | ExtentManager.getExtentTest().assignAuthor(String.valueOf(author));
75 | }
76 | }
77 |
78 | public static void addCategories(CategoryType[] categoryTypes) {
79 | for (CategoryType categoryType : categoryTypes) {
80 | ExtentManager.getExtentTest().assignCategory(String.valueOf(categoryType));
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/main/java/com/automation/reports/ExtentManager.java:
--------------------------------------------------------------------------------
1 | package com.automation.reports;
2 |
3 | import com.aventstack.extentreports.ExtentTest;
4 | import lombok.AccessLevel;
5 | import lombok.NoArgsConstructor;
6 |
7 | @NoArgsConstructor(access = AccessLevel.PRIVATE)
8 | public final class ExtentManager {
9 |
10 | private static final ThreadLocal threadLocalExtentTest = new ThreadLocal<>();
11 |
12 | public static ExtentTest getExtentTest() {
13 | return threadLocalExtentTest.get();
14 | }
15 |
16 | static void setExtentTest(ExtentTest test) {
17 | threadLocalExtentTest.set(test);
18 | }
19 |
20 | static void unload() {
21 | threadLocalExtentTest.remove();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/automation/reports/ExtentReport.java:
--------------------------------------------------------------------------------
1 | package com.automation.reports;
2 |
3 | import com.automation.exceptions.ReportInitializationException;
4 | import com.aventstack.extentreports.ExtentReports;
5 | import com.aventstack.extentreports.reporter.ExtentSparkReporter;
6 | import com.aventstack.extentreports.reporter.configuration.Theme;
7 | import lombok.AccessLevel;
8 | import lombok.NoArgsConstructor;
9 |
10 | import java.awt.Desktop;
11 | import java.io.File;
12 | import java.io.IOException;
13 | import java.net.InetAddress;
14 | import java.util.Objects;
15 |
16 | import static com.automation.constants.FrameworkConstants.getExtentReportPath;
17 |
18 | @NoArgsConstructor(access = AccessLevel.PRIVATE)
19 | public final class ExtentReport {
20 |
21 | private static final ExtentSparkReporter extentSparkReporter = new ExtentSparkReporter(getExtentReportPath());
22 | private static ExtentReports extentReports;
23 |
24 | /**
25 | * This method is to initialize the Extent Report
26 | */
27 | public static void initExtentReport() {
28 | try {
29 | if (Objects.isNull(extentReports)) {
30 | extentReports = new ExtentReports();
31 | extentReports.attachReporter(extentSparkReporter);
32 | InetAddress ip = InetAddress.getLocalHost();
33 | String hostname = ip.getHostName();
34 | extentReports.setSystemInfo("Host Name", hostname);
35 | extentReports.setSystemInfo("Environment", "API Automation - RestAssured");
36 | extentReports.setSystemInfo("User Name", System.getProperty("user.name"));
37 | extentSparkReporter.config().setDocumentTitle("HTML Report");
38 | extentSparkReporter.config().setReportName("API Automation Test");
39 | extentSparkReporter.config().setTheme(Theme.DARK);
40 | }
41 | } catch (Exception e) {
42 | throw new ReportInitializationException("Failed to initialize extent report - " + e.getMessage());
43 | }
44 | }
45 |
46 | public static void createTest(String testCaseName) {
47 | ExtentManager.setExtentTest(extentReports.createTest(testCaseName));
48 | }
49 |
50 | public static void flushExtentReport() {
51 | if (Objects.nonNull(extentReports)) {
52 | extentReports.flush();
53 | }
54 | ExtentManager.unload();
55 | try {
56 | Desktop.getDesktop().browse(new File(getExtentReportPath()).toURI());
57 | } catch (IOException e) {
58 | e.printStackTrace();
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/main/java/com/automation/utils/ApiUtils.java:
--------------------------------------------------------------------------------
1 | package com.automation.utils;
2 |
3 | import io.restassured.response.Response;
4 | import lombok.AccessLevel;
5 | import lombok.NoArgsConstructor;
6 | import lombok.SneakyThrows;
7 |
8 | import java.nio.file.Files;
9 | import java.nio.file.Paths;
10 |
11 | @NoArgsConstructor(access = AccessLevel.PRIVATE)
12 | public final class ApiUtils {
13 |
14 | @SneakyThrows
15 | public static String readJsonAndGetAsString(String filepath) {
16 | return new String(Files.readAllBytes(Paths.get(filepath)));
17 | }
18 |
19 | @SneakyThrows
20 | public static void storeStringAsJsonFile(String filepath, Response response) {
21 | Files.write(Paths.get(filepath), response.asByteArray());
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/automation/utils/AssertionKeys.java:
--------------------------------------------------------------------------------
1 | package com.automation.utils;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Getter;
5 |
6 | @Getter
7 | @AllArgsConstructor
8 | public class AssertionKeys {
9 |
10 | private String jsonPath;
11 | private Object expectedValue;
12 | private Object actualValue;
13 | private String result;
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/automation/utils/AssertionUtils.java:
--------------------------------------------------------------------------------
1 | package com.automation.utils;
2 |
3 | import com.automation.reports.ExtentLogger;
4 | import com.automation.reports.ExtentManager;
5 | import com.aventstack.extentreports.markuputils.MarkupHelper;
6 | import io.restassured.response.Response;
7 |
8 | import java.util.ArrayList;
9 | import java.util.List;
10 | import java.util.Map;
11 | import java.util.Optional;
12 | import java.util.Set;
13 |
14 | public class AssertionUtils {
15 |
16 | private AssertionUtils() {}
17 |
18 | public static void assertExpectedValuesWithJsonPath(Response response, Map expectedValuesMap) {
19 |
20 | List actualValueMap = new ArrayList<>();
21 | actualValueMap.add(new AssertionKeys("JSON_PATH", "EXPECTED_VALUE", "ACTUAL_VALUE", "RESULT"));
22 | boolean allMatch = true;
23 |
24 | Set jsonPaths = expectedValuesMap.keySet();
25 | for(String jsonPath : jsonPaths) {
26 | Optional