github.com/saucelabs/saucectl@v0.175.1/internal/cypress/code/parser.go (about) 1 package code 2 3 import ( 4 "regexp" 5 "strings" 6 ) 7 8 // Functions to parse cypress spec files for testcases and their metadata (e.g. 9 // test titles and tags). 10 // The general strategy is to parse in multiple passes; the first pass extracts 11 // testcase definitions (e.g. it('some test title', { tags: '@tag' }, () => ...) 12 // and subsequent passes extract the titles and tags. 13 14 var ( 15 reTestCasePattern = regexp.MustCompile(`(?m)^ *(?:it|test|context|describe)(?:\.\w+)?(\([\s\S]*?,\s*(?:function)?\s*\()`) 16 reTitlePattern = regexp.MustCompile(`\(["'\x60](.*?)["'\x60],\s*?(?:function)?|[{(]`) 17 reMultiTagPattern = regexp.MustCompile(`tags\s*:\s*\[([\s\S]*?)\]`) 18 reSingleTagPattern = regexp.MustCompile(`tags\s*:\s*['"](.*?)["']`) 19 ) 20 21 // TestCase describes the metadata for a cypress test case parsed from a cypress spec file. 22 type TestCase struct { 23 // Title is the name of the test case, the first argument to `it|test`. 24 Title string 25 // Tags is an optional list of tags. This is simply a space delimited 26 // concatenation of all tags defined for the testcase. 27 Tags string 28 } 29 30 // Parse takes the contents of a test file and parses testcases 31 func Parse(input string) []TestCase { 32 matches := reTestCasePattern.FindAllStringSubmatch(input, -1) 33 34 var testCases []TestCase 35 for _, m := range matches { 36 tc := TestCase{} 37 argSubMatch := m[1] 38 39 tc.Title = parseTitle(argSubMatch) 40 tc.Tags = parseTags(argSubMatch) 41 42 testCases = append(testCases, tc) 43 } 44 45 return testCases 46 } 47 48 func parseTitle(input string) string { 49 titleMatch := reTitlePattern.FindStringSubmatch(input) 50 if titleMatch != nil { 51 return titleMatch[1] 52 } 53 54 return "" 55 } 56 57 func parseTags(input string) string { 58 var tags []string 59 tagMatch := reSingleTagPattern.FindStringSubmatch(input) 60 if tagMatch == nil { 61 tagMatch = reMultiTagPattern.FindStringSubmatch(input) 62 } 63 if tagMatch != nil { 64 rawTags := strings.Split(tagMatch[1], ",") 65 for _, t := range rawTags { 66 t = strings.TrimSpace(t) 67 if t != "" { 68 tags = append(tags, strings.Trim(t, `"'`)) 69 } 70 } 71 return strings.Join(tags, " ") 72 } 73 return "" 74 }